I need insert 2 records in differents tables, - sql

I need to insert 2 records into 2 different tables. The problem is that the two records will be with the same Id.
For example :
I have my Mannto table, with its IdMan and oters fields. I also have my Service table, with its IdServ.
What can I do to make this one equal? I am using Postgre. The Id of the Mannto table is serial and I need to use that one as a Foreign key in the Service table
I tried the following, but it does not work:
Insert into Mannto ( idMan, field 1 field2 ...etc)
values ( default, 'f1', 'f2'...etc)
Insert into Service ( idServ, fkMannto, field1...etc)
values (default, (in this part I need the same ManntoId called idMan), 'f1')
Thank you for any help you can provide!

INSERT INTO Mannto ( field1, field2 ...etc) VALUES ( 'f1', 'f2'...etc)
RETURNING idMan;
http://www.postgresql.org/docs/current/static/sql-insert.html

When field idMan uses a sequence to create a new value, you can refer to this value in the next INSERT using CURRVAL():
BEGIN; -- start transaction
INSERT INTO Mannto ( idMan, field 1 field2 ...etc)
VALUES ( default, 'f1', 'f2'...etc);
INSERT INTO Service ( idServ, fkMannto, field1...etc)
VALUES (default, currval('name_of_the_sequence') , 'f1');
COMMIT; -- commit both inserts

Maybe it's not the best solution but you could use a trigger.
CREATE TRIGGER MannToTrigger
AFTER INSERT OR UPDATE OR DELETE ON MannTo
FOR EACH ROW EXECUTE PROCEDURE insertService();
Fetch your MannTo inserted last code and throw the procedure after each insert.

Related

SQL Server use SCOPE_IDENTITY() for insert into with select command

Hello I have one table whose name is
PERSO_DATA(Id,refPerso,,Col1,Col2,Col3,Col4,Col5)
and I have
PERSO_DATA_QUEUE(Id,refPersoData,refVideo)
Firstly I will insert to datas to PERSO_DATA then I will take Id of inserted data and isnsert to another table as refPersoData.
INSERT INTO PERSO_DATA(refPerso,Col1,Col2,Col3,Col4,Col5)
SELECT #refPerso,pa.Col1,pa.Col2,pa.Col3,pa.Col4,pa.Col5 FROM #PERSODATA pa
SET #refPersoData=SCOPE_IDENTITY()
When I write like that i insert all datas but can't take the Id for each data
INSERT INTO PERSO_DATA_QUEUE(refVideoQueue,refPersoData)
SELECT #refVideoQueue,#refPersoData
so code above it add only one.But I want if I have 10 data to insert PERSO_DATA I need to also insert PERSO_DATA_QUEUE table 10 data with inserted Ids.
How can I do this? I couldn't find a solution.
Thanks in advance
Try this code:
CREATE TABLE #temp ([Id] [bigint] NOT NULL);
INSERT INTO PERSO_DATA(refPerso,Col1,Col2,Col3,Col4,Col5)
OUTPUT INSERTED.Id
INTO #temp (Id)
SELECT #refPerso,pa.Col1,pa.Col2,pa.Col3,pa.Col4,pa.Col5
FROM #PERSODATA pa;
INSERT INTO PERSO_DATA_QUEUE(refVideoQueue,refPersoData)
SELECT #refVideoQueue, Id
FROM #temp;
The solution might be combining either cursor or loop and any iterator - like ROW_NUMBER() in your temp table.
Then - use SCOPE_IDENTITY() in it to get created IDENTITY value.

Advance Replace in insert scripts

I have below 2 insert statements which i took the export from sql developer from dev environment. I have delete those records from dev afterwards. Now i want to run this insert statement again in dev because those are my back up but i am getting error as virtual column which is ORD_DAYID cannot be used inside insert script. So i want to exclude this column and also the respective values using replace function or any tools which i dont know. I didnt know previously that i have virtual column for this table. I would like to know is there any tool or function where i can select ORD_DAYID and also the respective values get selected and then i can delete those and then i can be able to run this insert statement again in test enviornment.
P.S i have mentioned only 2 sample insert statements but there are 1000 insert statements. So its very difficult to manually delete this ORD_DAYID from this insert statements with respective values.
Insert into test_ord (IS_GRP,ORD_DAYID,REF_CAMPA_CODE) values (1,20150813,null);
Insert into test_ord (IS_GRP,ORD_DAYID,REF_CAMPA_CODE) values (1,20150828,null);
You can edit your INSERT statements using regular expressions, in an editor such as Notepad++.
So to change this ...
Insert into test_ord (IS_GRP,ORD_DAYID,REF_CAMPA_CODE) values (1,20150813,null);
... into this ...
Insert into test_ord (IS_GRP,REF_CAMPA_CODE) values (1,null);
You need a search pattern of:
Insert into test_ord \(IS_GRP,ORD_DAYID,REF_CAMPA_CODE\) values \(([0-9]+),([0-9]+),null\);
and a replace pattern of:
Insert into test_ord \(IS_GRP,REF_CAMPA_CODE\) values \(\1,null\);
Obviously you will need to refine the search pattern to cater for all the different values of IS_GRP, and REF_CAMPA_CODE in your 1000 statements.
" is there any way where we can count the place of column and value and replace it with null"
No. The snag with virtual columns is that they cannot be referenced in INSERT or UPDATE statements. So you need to totally exclude it from the projection.
"i am not able to find those option in notepad++"
Really? Search and replace is not an exotic option:
From the menu: Search > Find > Replace [tab] (or [ctrl]+h)
As the search mode select the regular expression radio button
create an auxiliary table without virtual columns.
Restore your data to this auxiliary table.
Transfer the data from the auxiliary table to the original table.
-- this is your table
create table mytab(A number, b number, s as (a+b));
--fill it with data
insert into mytab(a,b) values(1,1);
insert into mytab(a,b) values(1,2);
insert into mytab(a,b) values(2,1);
insert into mytab(a,b) values(2,2);
commit;
-- check its content
select * from mytab;
-- now delete the rows
delete from mytab;
commit;
-- restore your data
--------------------
-- create a table similar the table you want to restore
-- but the virtual colums as regular columns.
create table ctas as
select * from mytab where 1!=0;
-- insert your backup data
insert into ctas(a,b,s) values(1,1,2);
insert into ctas(a,b,s) values(1,2,3);
insert into ctas(a,b,s) values(2,1,3);
insert into ctas(a,b,s) values(2,2,4);
commit;
-- transfer the data to the table you want to restore
insert into mytab(a,b) select a,b from ctas;

How to insert autoincrementing id from one table into another in one command (using returning)?

I've attempted the following:
INSERT INTO second_table(id, somethingelse)
VALUES(
(INSERT INTO first_table(post_text) VALUES('a text') RETURNING id),
'abcd123'
);
I know how to do select with 2 query, but I'm trying to avoid any concurrency issue by doing these 2 insertions at once. Above gives me the following error:
ERROR: syntax error at or near "INTO"
LINE 3: (INSERT INTO first_table(post_text) VALUES('a text...
I'm trying to insert auto-incrementing id from first_table into second_table when a row is inserted into first_table.
Use a data modifying CTE:
with first_insert as (
INSERT INTO first_table(post_text)
VALUES('a text')
RETURNING id
)
INSERT INTO second_table(id, somethingelse)
select id, 'abcd123'
from first_insert;
Try creating a trigger to be executed whenever a row is inserted in first table.
something like:
CREATE TRIGGER trigger_name AFTER INSERT OF post_text
ON first_table
[
INSERT INTO second_table(id, somethingelse)
VALUES(
(select id from first_table where post_text='a text'),
'abcd123'
);
];
You need to run below command to off identity column
Set Identity_Insert [TableName] Off

ORACLE TRIGGER INSERT INTO ... (SELECT * ...)

Trigger with Insert into (select * ...)
I'm trying it.
INSERT INTO T_ USERS SELECT * FROM USERS WHERE ID = :new.ID;
not working...
this work.
INSERT INTO T_USERS(ID) VALUES(:new.ID);
Trigger
create or replace trigger "TRI_USER"
AFTER
insert on "USER"
for each row
begin
INSERT INTO T_USER SELECT * FROM USER WHERE ID = :new.ID;
end;​
this work.
INSERT INTO T_USERS(ID) VALUES(:new.ID);
So if it fits to you then try this:
INSERT INTO T_USER(ID) SELECT ID FROM USER WHERE ID = :new.ID;
If you want to select one or more rows from another table, you have to use this syntax:
insert into <table>(<col1>,<col2>,...,<coln>)
select <col1>,<col2>,...,<coln>
from ...;
Perhaps you could post the actual error you are experiencing?
Also, I suggest that you rethink your approach. Triggers that contain DML introduce all sorts of issues. Keep in mind that Oracle Database may need to restart a trigger, and could therefore execute your DML multiple times for a particular row.
Instead, put all your related DML statements together in a PL/SQL procedure and invoke that.
Its not about your trigger but because of INSERT statement
here insert statement works as below
INSERT INTO <TABLE>(COL1,COL2,COL3) VALUES (VAL1,VAL2,VAL3); --> If trying to populate value 1 by one.
INSERT INTO <TABLE>(COL1,COL2,COL3) --> If trying to insert mult vales at a time
SELECT VAL1,VAL2,VAL3 FROM <TABLE2>;
The number of values should match with number of columsn mentioned.
Hope this helps you to understand

Insert into a temporary table and update another table in one SQL query (Oracle)

Here's what I'm trying to do:
1) Insert into a temp table some values from an original table
INSERT INTO temp_table SELECT id FROM original WHERE status='t'
2) Update the original table
UPDATE original SET valid='t' WHERE status='t'
3) Select based on a join between the two tables
SELECT * FROM original WHERE temp_table.id = original.id
Is there a way to combine steps 1 and 2?
You can combine the steps by doing the update in PL/SQL and using the RETURNING clause to get the updated ids into a PL/SQL table.
EDIT:
If you still need to do the final query, you can still use this method to insert into the temp_table; although depending on what that last query is for, there may be other ways of achieving what you want. To illustrate:
DECLARE
id_table_t IS TABLE OF original.id%TYPE INDEX BY PLS_INTEGER;
id_table id_table_t;
BEGIN
UPDATE original SET valid='t' WHERE status='t'
RETURNING id INTO id_table;
FORALL i IN 1..id_table.COUNT
INSERT INTO temp_table
VALUES (id_table(i));
END;
/
SELECT * FROM original WHERE temp_table.id = original.id;
No, DML statements can not be mixed.
There's a MERGE statement, but it's only for operations on a single table.
Maybe create a TRIGGER wich fires after inserting into a temp_table and updates the original
Create a cursor holding the values from insert and then loop through the cursor updating the table. No need to create temp table in the first place.
You can combine steps 1 and 2 using a MERGE statement and DML error logging. Select twice as many rows, update half of them, and force the other half to fail and then be inserted into an error log that you can use as your temporary table.
The solution below assumes that you have a primary key constraint on ID, but there are other ways you could force a failure.
Although I think this is pretty cool, I would recommend you not use it. It looks very weird, has some strange issues (the inserts into TEMP_TABLE are auto-committed), and is probably very slow.
--Create ORIGINAL table for testing.
--Primary key will be intentionally violated later.
create table original (id number, status varchar2(10), valid varchar2(10)
,primary key (id));
--Create TEMP_TABLE as error log. There will be some extra columns generated.
begin
dbms_errlog.create_error_log(dml_table_name => 'ORIGINAL'
,err_log_table_name => 'TEMP_TABLE');
end;
/
--Test data
insert into original values(1, 't', null);
insert into original values(2, 't', null);
insert into original values(3, 's', null);
commit;
--Update rows in ORIGINAL and also insert those updated rows to TEMP_TABLE.
merge into original original1
using
(
--Duplicate the rows. Only choose rows with the relevant status.
select id, status, valid, rownumber
from original
cross join
(select 1 rownumber from dual union all select 2 rownumber from dual)
where status = 't'
) original2
on (original1.id = original2.id and original2.rownumber = 1)
--Only math half the rows, those with rownumber = 1.
when matched then update set valid = 't'
--The other half will be inserted. Inserting ID causes a PK error and will
--insert the data into the error table, TEMP_TABLE.
when not matched then insert(original1.id, original1.status, original1.valid)
values(original2.id, original2.status, original2.valid)
log errors into temp_table reject limit 999999999;
--Expected: ORIGINAL rows 1 and 2 have VALID = 't'.
--TEMP_TABLE has the two original values for ID 1 and 2.
select * from original;
select * from temp_table;