Number of Records in Insert Statement (Oracle) - 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.

Related

Stored procedure inserting only one rows after the loop is over in 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).

How to Insert a data along with update on same duplicate record

I want to insert a one or more records in table A.
But same record already existing in records with status Active
CREATE PROCEDURE Test
AS
BEGIN
INSERT INTO A (x,y,z,status)
SELECT data FROM A WHERE some condtion;
... Here i want to update table A status column into 'N', if the inserted data already existing in table A Compared with x,y,z column.
EXCETION
---Handled
END;
You can try this:
MERGE INTO target_table t
USING source_table s
ON (t.id = s.id)
WHEN MATCHED THEN
UPDATE SET t.col1 = s.col1
WHEN NOT MATCHED THEN
INSERT (col1, col2) VALUES (s.col1, s.col2);
Documentation Link: https://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_9016.htm#SQLRF01606
What you probably want to do is a merge-statement. The merge statement checks if the dataset already exists. In this case you can formulate an update statement. For example, you could update the status. If not, the new dataset will be inserted.
For further information you should hava a look here.
The merge is the way to go. Another approach is first updating all the rows that match the criteria and after do the insert.
However, if your problem is how to differentiate the 2 rows, use the pseudo-column ROWID.

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.

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