Stored procedure inserting only one rows after the loop is over in ORACLE - oracle

I have a procedure which calculates and has 3 rows for inserting the data into the table. So After loop I am trying to insert those rows in the table. But only first row is getting inserted into the table.
Below is link of my procedure.
Procedure link

You're kidding? A ~1.000 lines of unformatted procedure?
Anyway, here you go: as insert is *out of the loop, it executes only once. Move it into the loop (i.e. before the END LOOP statement).

Related

PL/SQL ONLY using a cursor to retrieve data from 2 tables into a new table

Hi I need to create a new table to store the data of two tables. Then I would need to create a stored procedure to transfer the data from the two tables into the new one. I had no problem transferring the data from the first table to the new table, the problem arises when i transfer the data from the second table to the new table. Because instead of being inserted in the row that matches its pubid, it is being inserted into a new row instead.
You're quite close, I'd say.
In the second loop, you shouldn't INSERT, but UPDATE existing row.
Cursor you declared:
CURSOR cur_proceedings IS
SELECT pubid, year FROM proceedings;
You've used it here:
OPEN cur_proceedings;
LOOP
FETCH cur_proceedings INTO v_proceedings;
EXIT WHEN cur_proceedings%NOTFOUND;
-- Instead of INSERT:
-- INSERT INTO publication_master(proceeding_year)
-- VALUES(v_proceedings.year);
-- use UPDATE:
update publication_master m set
m.proceeding_year = v_proceedings.year
where m.pubid = v_proceedings.pubid;
END LOOP;
CLOSE cur_proceedings;

Mutating table exception is not occurring

I have created a trigger and was expecting a mutating table error in below case but didn't get one through normal insert but getting an error while inserting using a query. I am not sure which concept I am missing here.
drop table temp;
create table temp (id number,name varchar2(500),is_active number);
create or replace trigger temp_trg before insert on temp
for each row
declare
v_count number;
begin
select count(1) into v_count from temp;
update temp set is_active=0 where is_active=1 and id=:new.id;
end;
/
select * from temp;
insert into temp values (1,'xyz',1);
insert into temp values (1,'xyz',1);
insert into temp select 1,'xyz',1 from dual;
getting an error while inserting using a query.
Mutating table occurs when we query the table which owns the trigger. Specifically it happens when Oracle can't guarantee the outcome of the query. Now when you insert a single row into the table Oracle can predict the outcome of the query when the FOR EACH ROW trigger fires, because it's a single row.
But with an INSERT FROM query Oracle is confused: should the count be the final figure including all the rows selected by the query or just a rolling count? The answer seems straightforward in this case but it's easy to imagine other queries where the answer is not clear cut. Rather than evaluate each query on its predictability Oracle enforces a plain fiat and hurls ORA-04091 for all query driven inserts.
The restriction on Mutating Tables applies to all triggers that use FOR EACH ROW clause except when either of the following is true:
the trigger fires on BEFORE event, i.e. the data wasn't actually changed
it is known that only one row will be affected - INSERT ... VALUES is the only DML that meets this condition

Get the no. of rows returned from sys_refcursor

I am writing an Oracle stored procedure with an OUT parameter as SYS_REFCURSOR.
The procedure does something like below:
open ref_cursorA for select * from tableA
save the no. of records retrieved to another table.
return the ref_cursorA for generating an Excel report.
However, there is no way to know the number of rows retrieved before fetching from the cursor, but I really need to save the no. of rows retrieved in the s.p. What should I do in this scenario?
When you open a cursor, the query hasn't been executed yet. It will be executed when you fetch the result rows. And most likely the execution will be piecewise, i.e. a few rows at a time.
So the number of rows is only know when the last row has been fetched.
If you really need the number of rows in your stored procedure, you'll have to execute an additional query that just counts the number of rows before you open and return the cursor for the main query:
select count(*) into var from tableA
Save the the number of rows in a separate table
open ref_cursorA for select * from tableA
return cursorA
Note:.Depending on your transaction isolation level, the COUNT(*) query will return a slightly different count if data is inserted and deleted at the same time.

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

Number of Records in Insert Statement (Oracle)

I'd like to report on the number of records inserted in an Oracle insert statement. I'm inserting from a statement, so I could run my select twice and a count, but I'd rather keep it all in a single statement. Is there a way?
Doing an INSERT in PL/SQL SQL%ROWCOUNT gives the number of inserted rows.
Doing an INSERT in C# cmd.ExecuteNonQuery() returns the number of inserted rows.

Resources