How to use new ID for subsequent inserts in same transaction - oracle

Using Oracle, we have 2 tables - Parent and Child.
We have the ID column as GUID in Parent table and this value is being created by a trigger before insert.
Now while inserting records in same transaction, I need to
- First add a record to Parent table, then
- Use the new GUID created in trigger to add records to child table
How do I retrieve this new GUID for subsequent inserts?

you can use returning into clause of insert statement
INSERT INTO parent VALUES (col1, ...)
RETURNING <your id column > INTO < variable>;
insert into child (parent_id) values (< variable>);

Related

Disparity between populated id column and returned value from hibernate after save

A sequence is used to generate id for a customer table and then using trigger to populate the id column as a varchar value.
The trigger is
CREATE OR REPLACE TRIGGER USER_ID_TRIGGER
before insert on CUSTOMER
REFERENCING NEW AS New OLD AS Old
for each row
begin
-- :new.user_id := 'CUST' || :new.user_id ;
select 'CUST' || SEQ_CUSTOMER_ID.nextval into :new.user_id from dual;
end USER_ID_TRIGGER;
So, each insert in the column is like 'CUST1', 'CUST3', etc.
The trigger can't be changed.
I am using hibernate save(customer) method to save customer objects in the db. Problem is the return id value I am getting is (as expected) different from the one that is ultimately saved in the table.
For example, if the id populated in the column is 'CUST19', the hibernate code returns 18.
My question is, if the code returns a value of 210, will it be safe for me to assume that the populated value is CUST211?

Statement level Trigger or Row Level Trigger

Which trigger to use - Statement or Row level?
If I use row level trigger , how to restrict it to insert data in tracking table only once for a group of entries in VALUES table
Database Schema -
ITEM_VERSIONS TABLE - Item_id,Version id,start_version_id,end_version_id
ITEM_VALUES_TABLE- Value Id, Value, Item_id, Start_version , End Version
Each time an item is created :
ITEM_VERSIONS TABLE - This table stores all the information of Item Versions.
For 1 item version, it has 1 row.
ITEM_VALUES_TABLE - This has all the values info .
So for 1 item , this table has 15-20 rows for each value attribute. Lets say Item_date , color etc
I want to create a trigger on ITEM_VALUES_TABLE and insert the version id in the tracking table.
To get version id, I have to use ITEM_VERSIONS TABLE to get the version id of the item and then update in the tracking table

How can I move existing records from parent table to newly created child table with the help of triggers (Oracle)?

I want to create a trigger wherein the child table pulls all the exisiting records from parent table.
I have created child tables referencing the parent table primary key as foreign key in new table
CREATE OR REPLACE TRIGGER trigger name
AFTER INSERT ON table_name(parent_table)
FOR EACH ROW
BEGIN
insert statement for child table;
END;
Above trigger is created for records which will be inserting post to child table creation, I would like to push all old records (which were present prior to child table creation) to the new child table. Will triggers help in pulling all the old records ?
Obviously NO!!
The trigger will start inserting records to the child table from the parent table post creation of trigger. Records inserted into parent table prior to trigger creation need to be inserted manually.
If you want to pull all records before the creation of trigger into child table from parent table then you need to write one-time INSERT query as following:
INSERT INTO CHILD_TABLE
SELECT * FROM PARENT_TABLE P
WHERE NOT EXISTS (SELECT 1 FROM CHILD_TABLE C WHERE P.PK = C.FK);
-- OR --
INSERT INTO CHILD_TABLE
SELECT * FROM PARENT_TABLE P
WHERE P.PK IN
(SELECT PK FROM PARENT_TABLE
MINUS
SELECT FK FROM CHILD_TABLE
)
Cheers!!

Inserting an empty row

This is so simple it has probably already been asked, but I couldn't find it (if that's the case I'm sorry for asking).
I would like to insert an empty row on a table so I can pick up its ID (primary key, generated by an insert trigger) through an ExecuteScalar. Data is added to it at a later time in my code.
My question is this: is there a specific insert syntax to create an empty record? or must I go with the regular insert syntax such as "INSERT INTO table (list all the columns) values (null for every column)"?
Thanks for the answer.
UPDATE: In Oracle, ExecuteScalar on INSERT only returns 0. The final answer is a combination of what was posted below. First you need to declare a parameter, and pick up it up with RETURNING.
INSERT INTO TABLENAME (ID) VALUES (DEFAULT) RETURNING ID INTO :parameterName
Check this out link for more info.
You would not have to specify every single column, but you may not be able to create an "empty" record. Check for NOT NULL constraints on the table. If none (not including the Primary Key constraint), then you would only need to supply one column. Like this:
insert into my_table ( some_column )
values ( null );
Do you know about the RETURNING clause? You can return that PK back to your calling application when you do the INSERT.
insert into my_table ( some_column )
values ( 'blah' )
returning my_table_id into <your_variable>;
I would question the approach though. Why create an empty row? That would/could mean there are no constraints on that table, a bad thing if you want good, clean, data.
Basically, in order to insert a row where values for all columns are NULL except primary
key column's value you could execute a simple insert statement:
insert into your_table(PK_col_name)
values(1); -- 1 for instance or null
The before insert trigger, which is responsible for populating primary key column will
override the value in the values clause of the insert statement leaving you with an
empty record except PK value.

Create after insert trigger which updates record by getting value from other Oracle 11g table

I have two tables
Parent(id, name, occupation)
Child(id, name, gender,parent_id, parent_name, parent_occupation)
Now to insert value in child i'll run chi query
insert into Child(id,name,gender,parent_id) values(10,'XYZ','Male',15);
So now my requirement is when this insert query is executed a trigger will run and get name and occupation from parent table for id 15 (parent_id of the Child record) and add it to the newly inserted row in fields parent_name and parent_occupation respectively.
I am using Oracle 11g as my database.
You want something akin to this (though you'll need to add code to handle the exception):
CREATE OR REPLACE
TRIGGER ai_child_tg
AFTER INSERT ON child
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
BEGIN
SELECT name,
occupation
INTO :NEW.parent_name,
:NEW.parent_occupation
FROM parent
WHERE id = :NEW.parent_id;
EXCEPTION
WHEN no_data_found
THEN
<handle_your_exception_>
END ai_child_tg;
However, if your CHILD table is really a relational child to your PARENT table and there is a FK relationship in place (via the CHILD.PARENT_ID column) then storing the PARENT_NAME and PARENT_OCCUPATION columns in the CHILD table is logically redundant.
I'd query why you have those two columns in the CHILD table at all.
Hope it helps...

Resources