Insert instead of from select and inserted data - sql

I'm having trouble creating a trigger in a SQLite DB on a view that inserts values into 2 different tables and then inserts the "ID" values from those tables and values from the inserted data into a 3rd table. So basic idea is ....
CREATE TABLE [TBL1] (ID UNIQUE INT AUTOINCREMENT,VAL1);
CREATE TABLE [TBL2] (ID UNIQUE INT AUTOINCREMENT,VAL2);
CREATE TABLE [TBL3] (ID1 INT,ID2 INT,VAL3);
CREATE VIEW [v_TBL3] AS
SELECT (TBL1.VAL1,TBL2.VAL2,TBL3.VAL3)
FROM TBL3
INNER JOIN TBL1 ON TBL3.ID1 = TBL1.ID
INNER JOIN TBL2 ON TBL3.ID2 = TBL2.ID;
========== heres the problem ==========
CREATE TRIGGER [t_TBL3_INSERT] INSTEAD OF INSERT ON v_TBL3
BEGIN
INSERT OR IGNORE INTO [TBL1] (VAL1) VALUES NEW.VAL1;
INSERT OR IGNORE INTO [TBL2] (VAL2) VALUES NEW.VAL2;
INSERT INTO [TBL3] (ID1,ID2,v_TBL3.VAL3)
SELECT (TBL1.ID,TBL2.ID,VAL3)
FROM TBL1,TBL2,v_TBL3
WHERE TBL1.VAL1 = v_TBL3.VAL1 AND TBL2.VAL2 = v_TBL3.VAL2;
END;
I've looked on around on the net but I'm not finding quite what I need to get me there. Can someone help me get there?

You did not mention what your problem is, but when using proper SQL syntax, your schema would look like this:
CREATE TABLE TBL1 (ID INTEGER PRIMARY KEY AUTOINCREMENT, VAL1);
CREATE TABLE TBL2 (ID INTEGER PRIMARY KEY AUTOINCREMENT, VAL2);
CREATE TABLE TBL3 (ID1 INT, ID2 INT, VAL3);
CREATE VIEW v_TBL3 AS
SELECT TBL1.VAL1, TBL2.VAL2, TBL3.VAL3
FROM TBL3
INNER JOIN TBL1 ON TBL3.ID1 = TBL1.ID
INNER JOIN TBL2 ON TBL3.ID2 = TBL2.ID;
CREATE TRIGGER t_TBL3_INSERT
INSTEAD OF INSERT ON v_TBL3
BEGIN
INSERT OR IGNORE INTO TBL1 (VAL1) VALUES (NEW.VAL1);
INSERT OR IGNORE INTO TBL2 (VAL2) VALUES (NEW.VAL2);
INSERT INTO TBL3 (ID1, ID2, VAL3)
SELECT TBL1.ID, TBL2.ID, VAL3
FROM TBL1, TBL2, v_TBL3
WHERE TBL1.VAL1 = v_TBL3.VAL1 AND TBL2.VAL2 = v_TBL3.VAL2;
END;

Related

Trigger to insert same table after condition is satsified

I want to insert a row if the field 'Rem' is yes. I am using triggers. Here the issue is I want to insert the data in the same table. Could you please let me know if you have come across this scenario?
Example:
create table Table1
(
id int,
name varchar(100),
is_rem varchar(20)
);
create or replace trigger Table1Trigger
after insert
on Table1
for each row
when (new.is_rem ='yes')
begin
insert into Table1 (id, name, is_rem)
values (:new.id, :new.name, :new.is_rem);
end; /
If I am inserting the is_rem as yes, the table should have two rows of the same data.
Below should works in MySQL
create table if not exists Table1 ( id int, name varchar(100), is_rem varchar(20) );
insert into Table1
select new_id as id, new_name as name, new_is_rem as is_rem
from Table2 where new_is_rem = 'yes';

Setting Postgresql variable from result of insert for future use

I have a table with a UUID key that is generated on insert. I need to use that key in multiple future inserts and want to store it in a variable.
CREATE TABLE table1 (UUID uuid PRIMARY KEY DEFAULT gen_random_uuid(), blah integer);
CREATE TABLE table2 (UUID uuid PRIMARY KEY DEFAULT gen_random_uuid(), UUID table1Uuid);
INSERT INTO TABLE1 (blah) values (1234);
INSERT INTO TABLE1 (blah) values (6789);
.....
INSERT INTO TABLE2 (table1Uuid theUuidMadeFromInsert1234);
I think I can make sure all the future inserts into TABLE2 are in the same session (maybe the same script) as those for TABLE1. Would like to do something like
uuid1234 = INSERT INTO TABLE1 (blah) values (1234);
uuid6789 = INSERT INTO TABLE1 (blah) values (6789);
.....
INSERT INTO TABLE2 (table1Uuid uuid1234);
but I can't get any syntax to work. I tried
create or replace function insertTable1 (junk integer)
RETURNS UUID
LANGUAGE plpgsql AS
$func$
declare
myUuid UUID;
BEGIN
insert into table1 (blah) values (junk) returning uuid into myUuid;
return myUuid;
END
$func$;
then doing something like set my.var.uuid = select insertTable1(1234) and insert into table2 (table1Uuid my.var.uuid) with various uses of current_setting
I have read many posts on SO, but can't find one that allows the value of the variable to outlast the function and be used
Is this what you want?
with t1 as (
insert into table1 (blah) values (1234), (6789)
returning *
)
insert into table2 (table1Uuid)
select uuid from t1 where blah = 1234;
The CTE inserts several rows in table1, then the outer query inserts in table2 the uuid that was generated for blah 1234.
Note that if you insert 1234 more than once in the CTE, the outer query will create as many rows in table2.
Alernatively, you can isolate the first insert in another CTE:
with
t1 as (insert into table1 (blah) values (1234) returning *),
t2 as (insert into table1 (blah) values (456), (789))
insert into table2 (table1Uuid) select uuid from t1

I need extract the data inserted into a table into two tables

I need extract the data inserted into a table and extract the data inserted into last table and insert into another table table
create table tab1 (id bigint identity(1,1), col_1 varchar(4))
create table tab2 (id bigint identity(1,1), col_1 varchar(4), id_tab1 bigint)
create table tab3 (id bigint identity(1,1), col_1 varchar(4), id_tab2 bigint)
create table tab4 (id bigint identity(1,1), col_1 varchar(4), id_tab3 bigint)
insert into tab1 (col_1)
values ('AAAA'),('BBBB'),('CCCC')
insert into tab2 (col_1, id_tab1)
output inserted.col_1, inserted.id into tab3 (col_1, id_tab2)
--I NEED DO: OUTPUT FROM TAB3 INTO TAB4
output inserted.tab3.col_1, inserted.tab3.id into tab4 (col_1, id_tab3)
select col_1, id
from tab1
The output clause requires an explicit INSERT. So, use temporary tables:
declare #t2ids table (col_1 varchar(4), id_tab2 int);
insert into tab2 (col_1, id_tab1)
output inserted.col_1, inserted.id into #t2ids (col_1, id_tab2);
declare #t3ids (col1 varchar(4), id_tab3);
insert into tab3 (col1, id_tab2)
output inserted.col_1, inserted.id into #t3ids (col_1, id_tab3)
select col_1, id_tab2
from #t2ids;
insert into tab4 (col_1, id_tab3)
select col_1, id_tab3
from #t3ids;
You seem to be attempting to implement an "insert cascade" - meaning that an insert into the first table will automatically insert default values to the related table, and from that to the next related table and so on (up to tab4).
I would use triggers instead of the output clause for such a thing - create a trigger for insert on each table that will insert the relevant records to the next one:
create trigger trg_tab2_insert on tab2 for insert
as
insert into tab3(col_1, id_tab2)
select col_1, id
from inserted
and then
create trigger trg_tab3_insert on tab3 for insert
as
insert into tab4(col_1, id_tab3)
select col_1, id
from inserted
Please note that for this to work nested trigger should be enabled (Which is the default state in SQL Server)
Can you not run it as one script?
for instance script.sql:
insert into tab2 (col_1,id_tab1) select col_1,id from tab1
insert into tab3 (col_1,id_tab2) select col_1,id from tab2
insert into tab4 (col_1,id_tab3) select col_1,id from tab3

Joining multiple table Sql trigger

Hi I am newbie to SQL trigger. since I tried and searched on online and I dont find any clear outcome.
so here is my problem.
I have three tables:
TABLE1 :
ID NAME (columns )
1 prabhu
TABLE2 :
Id COUNTRY (columns )
1 India
I want this to send to log table if anything like insert/update happen in table2
The SQL(DB2) trigger has to do the following and the result should be in log table like this
LOGTABLE:
ID NAME COUNTRY
1 prabhu India
Your help really appreciated.
Try this,
-- Create tables
create table table1(id int, empName varchar(20));
create table table2(id int, country varchar(20));
create table logtable(id int, empName varchar(20), country varchar(20));
-- Create trigger
CREATE TRIGGER logtableAfterInsert ON table2
after INSERT,DELETE,UPDATE
AS
BEGIN
declare #empid int;
declare #empname2 varchar(20);
declare #empcountry varchar(20);
select #empid=i.id from inserted i;
select #empcountry=i.country from inserted i;
select #empname2=tbl1.empName from table1 tbl1 where tbl1.id=#empid;
insert into logtable values(#empid,#empname2,#empcountry);
PRINT 'Inserted'
END
GO
After that insert the values,
insert into table1 values(1, 'prabhu');
insert into table2 values (1, 'India');
Check the results,
select * from table1;
select * from table2;
select * from logtable;
Hope this resolves...
BTW, You need to add the foreign key constraint.
CREATE OR REPLACE TRIGGER logtableAfterUpdate
AFTER UPDATE ON table2
REFERENCING NEW AS NAUDIT OLD AS OAUDIT
FOR EACH ROW MODE DB2SQL
--BEGIN --ATOMIC
insert into logtable
values(
(select id from table2 tbl2 where tbl2.id =OAUDIT.id),
(select empName from table1 tbl1 where tbl1.id=(select id from table2 tbl2 where tbl2.id =OAUDIT.id)),
(select country from table2 tbl2 where tbl2.id =OAUDIT.id)
);
--END;

How do I update a table based off the generated index key of an insert?

I'm created a temp table with most of the values I need to insert into a set of tables. From this temp table I have all the values I need for the insert to the first table, but the insert to the next table depends on the identity key generated by the insert to the first table.
I could very well just update my temp table after the first insert, but I'd like to try using the output clause.
I want something like this:
INSERT INTO Table1
<values from temp table>
OUTPUT <update my temp table with generated identity keys>
INSERT INTO Table2
<values from temp table including the output updated id column>
I think you better create another temp table (OR) table type variable and go from there as shown below. Cause I don't think you can update the same temp table from where you are inserting using output clause.
CREATE TABLE TestTable (ID INT not null identity primary key,
TEXTVal VARCHAR(100))
create TABLE #tmp(ID INT, TEXTVal VARCHAR(100))
create TABLE #tmp1(ID INT, TEXTVal VARCHAR(100))
CREATE TABLE TestTable1 (ID INT not null, TEXTVal VARCHAR(100))
INSERT #tmp (ID, TEXTVal)
VALUES (1,'FirstVal')
INSERT #tmp (ID, TEXTVal)
VALUES (2,'SecondVal')
INSERT INTO TestTable (TEXTVal)
OUTPUT Inserted.ID, Inserted.TEXTVal INTO #tmp1
select TEXTVal from #tmp
INSERT INTO TestTable1 (ID, TEXTVal)
select ID, TEXTVal from #tmp1
You could merge your temptable into Table1, and output the results to a variable table, then insert the original data joined to the variable table into Table2.
Example:
DECLARE #MyIDs TABLE (TempTableID int NOT NULL, Table1ID int NOT NULL)
MERGE INTO Table1
USING TempTable AS Tmp
ON Table1.SomeValue = Tmp.SomeValue
WHEN NOT MATCHED THEN
INSERT (col1, col2, col3, col4, col5)
VALUES (tmp.col1, tmp.col2, tmp.col3, tmp.col4, tmp.col5)
OUTPUT Tmp.ID
,Table1.ID
INTO #MyIDs;
INSERT INTO Table2 (col1, col2, col3, col4, col5, Table1ID)
SELECT tmp.col1, tmp.col2, tmp.col3, tmp.col4, tmp.col5, new.Table1ID
FROM TempTable tmp
JOIN #MyIDs new ON tmp.ID = new.TempTableID