Joining multiple table Sql trigger - sql

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;

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';

How to optimize a trigger?

CREATE TRIGGER T
ON TABLE_2
AFTER INSERT
AS
DECLARE #bought_t int,
#name_t varchar(20)
SELECT #name_t = name_t
FROM inserted
SELECT #bought_t = bought_t
FROM TABLE_1
WHERE name_t = #name_t
IF #bought_t < 100
BEGIN
UPDATE TABLE_1
SET bought_t = #bought_t + 1
WHERE TABLE_1.name_t = #name_t
END
ELSE
ROLLBACK TRANSACTION
The column (TABLE_1) I'm making the update to after the insert happens in the 'TABLE_2' is supposed to hold values between 50 and 100. So I'm asking If this trigger is as professional and optimized as It could be? or I have some flaws that could lead to bugs/security issues.
Basically, you need to completely rewrite your trigger to be set-based and to be able to work with multiple rows in the Inserted pseudo table.
Fortunately, that also makes it easier - in my opinion - try something like this:
CREATE TRIGGER T
ON TABLE_2
AFTER INSERT
AS
UPDATE T1
SET bought_t = bought_t + 1
FROM TABLE_1 T1
INNER JOIN Inserted i ON i.name_t = T1.name_t
WHERE T1.bought_t < 100
UPDATE: demo to prove this works:
-- create the two tables
CREATE TABLE TABLE_2 (ID INT NOT NULL IDENTITY(1,1), ProdName VARCHAR(50))
CREATE TABLE TABLE_1 (ProdName VARCHAR(50), Bought INT)
GO
-- create trigger on "TABLE_2" to update "TABLE_1"
CREATE TRIGGER T2Insert
ON TABLE_2
AFTER INSERT
AS
UPDATE T1
SET Bought = Bought + 1
FROM TABLE_1 T1
INNER JOIN Inserted i ON T1.ProdName = i.ProdName
WHERE T1.Bought < 100
GO
-- initialize TABLE_1 with some seed data
INSERT INTO dbo.TABLE_1 (ProdName, Bought)
VALUES ( 'Prod1', 0), ('Prod2', 20), ('Prod3', 40), ('Prod4', 40), ('Prod100', 100)
-- insert new values into TABLE_2
INSERT INTO dbo.TABLE_2 (ProdName)
VALUES ('Prod1'), ('Prod100'), ('Prod2'), ('Prod4')
-- get data to check
SELECT * FROM dbo.TABLE_1
This renders output:
As you can easily see:
Prod1, Prod2, Prod4 that were inserted caused an update of the value Bought
Prod100 which was also inserted did not cause an update of Bought
UPDATE #2: if you need to be able to insert multiple identical values at once, you need to slightly enhance your trigger like this:
CREATE TRIGGER T2Insert
ON TABLE_2
AFTER INSERT
AS
-- declare table variable to hold names and update counts
DECLARE #UpdateCount TABLE (Name VARCHAR(50), UpdCount INT)
-- from the "Inserted" table, determine which names are being
-- inserted how many times using GROUP BY
INSERT INTO #UpdateCount (Name, UpdCount)
SELECT ProdName, COUNT(*)
FROM Inserted
GROUP BY ProdName
-- now join to this temporary table, and update as many times
-- as needed (instead of +1 for all cases)
UPDATE T1
SET Bought = Bought + uc.UpdCount
FROM TABLE_1 T1
INNER JOIN #UpdateCount uc ON uc.Name = T1.ProdName
WHERE T1.Bought < 100
GO

Fill automatic data in second table when insert data in one table

I have two table Table1 and Table2 and structure of table as
Table1
Primary Key | Name
Table2
Primary Key | Table1_Id_pk | Status - true/false value
When I insert data into Table2 I want to automatically transfer that data in table1 from Table2 which have Status false.
You can create AFTER INSERT trigger:
CREATE TRIGGER DataMigration
ON Table2
AFTER INSERT
AS
BEGIN
INSERT INTO Table1
SELECT *
FROM TAble2
WHERe Status = 'false'
END
GO
Check this example, use ##identity to get inserted row-id and use that id for child table.
declare #t1 table (pk int identity(1,1) not null , name varchar(50) )
declare #t2 table (pk int identity(1,1) not null , t1pk int, status bit )
declare #new_table1Id int
insert into #t1 values( 'ajay')
set #new_table1Id = ##IDENTITY -This gives you last inserted id of #t1
insert into #t2 values( #new_table1Id , 0)
select * from #t1
select * from #t2
##IDENTITY official documentation

Prevent insertion of duplicates

I have a table with columns CompanyID, EmployeeCode. EmployeeCode is unique and CompanyID can be repeated. So we can keep a list of employees in Google, Apple etc.
I want a way to ensure that the same employee cannot be added if he/she is already in the database. What would be a good way to do this ? I'd prefer not to create additional columns or tables for this.
Create a UNIQUE constraint on the column where you want to prevent duplicates:
CREATE UNIQUE INDEX [IX_YourTableName_EmployeeCode] ON [YourTableName] (EmployeeCode)
Try this..
Create table UniqueTable
(
CompanyID int,
EmployeeCode int
)
--Insert dummy data
INSERT INTO UniqueTable(EmployeeCode ,CompanyID ) Values(1,200)
--When are Going to insert duplicate Ecmployeecode '1' then it will not insert data into table
INSERT INTO UniqueTable(EmployeeCode ,CompanyID )
Select 1,200 From UniqueTable t1
Left join UniqueTable t2 on 1=t2.EmployeeCode
WHERE t2.EmployeeCode IS NULL
--We are Going to insert different Ecmployeecode '2' it will insert into table
INSERT INTO UniqueTable(EmployeeCode ,CompanyID )
Select 2,300 From UniqueTable t1
Left join UniqueTable t2 on 2=t2.EmployeeCode
WHERE t2.EmployeeCode IS NULL
Try this
Create PROCEDURE [dbo].[sp_Emp_Insert]
#EmployeeCode nvarchar(50)
As
Begin
if Not Exists (select EmployeeCode from YOUR_TABlE where EmployeeCode =#EmployeeCode )
Begin
Insert QUERY
End
else
Return 0
End
End

Insert instead of from select and inserted data

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;