Using PL/SQL associative arrays - oracle

create or replace aArr is TABLE of varchar2 index by binary_integer;
create or replace bArr is TABLE of varchar2 index by binary_integer;
create or replace prc(oname aArr, iname bArr) as
begin
--Now i have two arrays
-- i want to insert or update into table using these two arrays
-- How can i do that with out using the loops.
-- is there any bulk insert or update.
end
Now I have two arrays. I want to insert or update into table using these two arrays. How can I do that with out using the loops? Is there any bulk insert or update?

If you have PL/SQL associative arrays, you can use bulk processing to insert the data into underlying database tables using FORALL.
The oracle documantation is here:
http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14261/forall_statement.htm
The syntax is similar to:
FORALL x IN INDICES OF <associative_array_name>
-- DML (INSERT or UPDATE etc)
It's a bit of a generic answer but you have asked a very generic question.
Hope this helps...

Related

How to drop and recreate Indexes inside PLSQL Stored Procedure

In PLSQL stored procedure, I would like to drop indexes and truncate the table
before inserting data into the table. Then I want to recreate the indexes afterwards . What is the best way of achieving this?
I need something similar like this
Begin:
Truncate Table
Drop index1
Drop index2
loop
--- other code
Insert data
commit;
end loop;
Create index1
Create index2
End;
We can't run DDL directly in PL/SQL.
The best approach is to use the Oracle built-in DBMS_UTILITY.EXEC_DDL_STATEMENT(). It's covered in the docs Find out more. But basically:
begin
DBMS_UTILITY.EXEC_DDL_STATEMENT('drop index index1')
DBMS_UTILITY.EXEC_DDL_STATEMENT('drop index index2')
DBMS_UTILITY.EXEC_DDL_STATEMENT('truncate table your_table')
....
Note that the commands are strings not SQL.
If you're inserting enough data to make it worthwhile dropping and re-creating the indexes then you probably want set operations rather than doing it in a loop. Set operations work on chunks of data rather then individual rows. Quite what approach is appropriate depends on how much data you have.
"I want to insert data from staging table and then joining with other table"
So the most efficient route is likely to be
insert into your_table
select /*+ append */ ....
from staging_table
join other_table
on ...
However, depending on your definition of "huge" you may need to use a PL/SQL bulk operation, with a FORALL insertion. That would require reading from your staging table in chunks, so it would entail a loop. Find out more
You can use dynamic SQL , specifically, execute immediate, based on your requirements:
Begin:
execute immediate 'truncate table statement';
execute immediate 'DROP index statement';
loop
--- other code
Insert data
commit;
end loop;
execute immediate 'Create index1 statement';
execute immediate 'Create index2 statement';
End;

Tsql table variable to Oracle PLSql

I am working on TSql to Plsql conversion.
There are several table variables declared and used in tsql, like
DECLARE #table_var table( id_ int ......)
WHILE ...
begin
insert into #table_var select ...
...
select * from #table_var..
I think in oracle global temporary table can be used, but the data will be maximum 10k rows.
How efficient global temporary tables in this case?
Is there any other way other than global temporary table and table types in Oracle to convert similar sql query?
Oracle version: oracle11g or oracle12c
Depending on your size of the data and task that you want to achieve-- you can use
Pl/sql record/table and bulk processing
hold data in to cursor and loop through it
if you want kind of query update -- you can use in-line view
(preserving primary key)

Creating a back up table trigger in Oracle

I have a table A which is constantly updated ( insert statements ) by one application. I want to create another table B which consists only few columns of table A. For this I thought of creating a trigger which triggered after insert on Table A, but I don't know how should I write the insert statement inside the trigger. I am not a database expert, so may be I am missing something simple. Please help.
Here is my trigger code:
CREATE OR REPLACE TRIGGER "MSG_INSERT_TRIGGER"
AFTER
insert on "ACTIVEMQ_MSGS"
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
begin
execute immediate 'truncate table MSG_BACKUP';
insert into MSG_BACKUP select * from ACTIVEMQ_MSGS;
COMMIT;
end;
This does not seem to be good idea: every time a new record gets inserted into Table A, delete everything from table B and copy all records from table A. This will be a huge performance issue, once there is many records in table A.
Wouldn't it be enough to create a view on the desired columns of table A?
If not, that is, you still want to "log" all inserts into an other table, then here you go. (I suppose you want to copy the following fields: f1, f2, f3)
CREATE OR REPLACE TRIGGER TR_AI_ACTIVEMQ_MSGS
AFTER INSERT ON ACTIVEMQ_MSGS
FOR EACH ROW
BEGIN
INSERT INTO MSG_BACKUP (f1, f2, f3)
VALUES (:new.f1, :new.f2, :new.f3);
END TR_AI_ACTIVEMQ_MSGS;
Inside an Oracle trigger the record values are available in de :new pseudo record. Your insert statement may look like this:
insert into B (column1, column2)
values (:new.tableA_col1,:new.tableA_col2)

Stored Procedure for copying data from one table to another

I have pairs of tables in the format TABLE and TABLE_TWIN now
TABLE is the main table with lots of data
TABLE_TWIN is a table with the exact same fields with a little data (different data)
Now I would like to copy all rows from TABLE_TWIN to TABLE using a stored procedure. I have many such tables and could like the stored procedure to take the table name(s) as parameter(s) so that I can use the same procedure for each table pair. I do not want to write long INSERT statements because these tables have around 50 attributes each.
I am not good with PL/SQL so I need some help here.
Thanks!
SQL is not so long... But if you prefer a procedure, here it is:
create or replace procedure table_copy(
p_tab_from varchar2,
p_tab_to varchar2)
is
begin
execute immediate 'insert into '||p_tab_to||' (select * from '||p_tab_from||')';
end;
insert into table_twin (select * from table)
should do it

Insert into oracle database

Hi I have a database with loads of columns and I want to insert couple of records for testing, now in order to insert something into that database I'd have to write large query .. is it possible to do something like this
INSERT INTO table (SELECT FROM table WHERE id='5') .. I try to insert the row with ID 5 but I think this will create a problem because it will try to duplicate a record, is it possible to change this ID 5 to let say 1000 then I'd be able to insert data without writing complex query and while doing so avoiding replication of data .. tnx
In PL/SQL you can do something like this:
declare
l_rec table%rowtype;
begin
select * into l_rec from table where id='5';
l_rec.id := 1000;
insert into table values l_rec;
end;
If you have a trigger on the table to handle the primary key from a sequence (:NEW.id = seq_sequence.NEXTVAL) then you should be able to do:
INSERT INTO table
(SELECT columns_needed FROM table WHERE whatever)
This will allow you to add in many rows at one (the number being limited by the WHERE clause). You'll need to select the columns that are required by the table to be not null or not having default values. Beware of any unique constraints as well.
Otherwise you'll be looking at PL/SQL or some other form of script to insert multiple rows.
For each column that has no default value or you want to insert the values other than default, you will need to provide the explicit name and value.
You only can use an implicit list (*) if you want to select all columns and insert them as they are.
Since you are changing the PRIMARY KEY, you need to enumerate.
However, you can create a before update trigger and change the value of the PRIMARY KEY in this trigger.
Note that the trigger cannot reference the table itself, so you will need to provide some other way to get the unique number (like a sequence):
CREATE TRIGGER trg_mytable_bi BEFORE INSERT ON mytable FOR EACH ROW
BEGIN
:NEW.id := s_mytable.nextval;
END;
This way you can use the asterisk but it will always replace the value of the PRIMARY KEY.

Resources