SQL Server trigger IF condition on other table - sql-server

In SQL Server, is possible to trigger an event based on a SELECT condition in another table?
Let's imaging this trigger in TABLE_1:
FOR INSERT AS
BEGIN
INSERT INTO TABLE_2 (ID, COD_CAT)
SELECT COD_ART,'X3'
FROM INSERTED
This trigger works fine and always.
I would like trigger that insert event only if INSERTED.COD_ART does not already exist in TABLE_2.
Any ideas?

use trigger on table1 and use 'if exists' before insert
...
FOR INSERT AS
BEGIN
IF not EXISTS
(SELECT COD_ART,'X3'
FROM INSERTED A LEFT JOIN TABLE_2 B
ON A.COD_ART = B.COD_ART
WHERE B.COD_ART IS NULL)
BEGIN
INSERT INTO TABLE_2 (ID, COD_CAT)
SELECT COD_ART,'X3'
FROM INSERTED
END
END

You can't have a selective trigger but you can insert selectively. Use LEFT JOIN to insert only non matching rows as below.
INSERT INTO TABLE_2 (ID, COD_CAT)
SELECT COD_ART,'X3'
FROM INSERTED A LEFT JOIN TABLE_2 B
ON A.COD_ART = B.COD_ART
WHERE B.COD_ART IS NULL

Related

SQL Server : AFTER INSERT trigger and INSERT INTO

I want to create a trigger that will fill up my sales history base after firing in the ORDER table.
I am creating a specific order in regular data base and after that this order automatically goes to sales_history database.
Below part works properly.
When I create a new order in regular database my sales_history database is growing with new ID_ORDERS, hooray! :)
ALTER TRIGGER [dbo].[InsertTrig]
ON [dbo].[ORDER]
AFTER INSERT
AS
IF EXISTS (SELECT *
FROM inserted i
WHERE i.ID_TYPE = 1) -- specific order type
BEGIN
INSERT INTO id.dbo.sales_history (id_order)
SELECT i.ID_ORDER FROM inserted i
END
The problem arises when I want join another table. The trigger stops working
ALTER TRIGGER [dbo].[InsertTrig]
ON [dbo].[ORDER]
AFTER INSERT
AS
IF EXISTS (SELECT *
FROM inserted i
WHERE i.ID_TYPE = 1) -- specific order type
BEGIN
INSERT INTO id.dbo.sales_history (id_order, id_item)
SELECT
inserted.ID_ORDER, ORDER_DETAILS.ID_ITEM
FROM
inserted
INNER JOIN
ORDER_DETAILS ON ORDER_DETAILS.ID_ORDER = inserted.ID_ORDER
END
I also tried this way, and still nothing :(
ALTER TRIGGER [dbo].[InsertTrig]
ON [dbo].[ORDER]
AFTER INSERT
AS
IF EXISTS (SELECT *
FROM inserted i
WHERE i.ID_TYPE = 1) -- specific order type
BEGIN
DECLARE #xyz AS numeric(18, 0)
SET #xyz = (SELECT inserted.ID_ORDER FROM inserted)
INSERT INTO id.dbo.sales_history (id_order, id_item)
SELECT
ORDER.ID_ORDER, ORDER_DETAILS.ID_ITEM
FROM
ORDER
INNER JOIN
ORDER_DETAILS ON ORDER_DETAILS.ID_ORDER = ORDER.ID_ORDER
WHERE
ORDER.ID_ORDER = #xyz
END
I want to create a trigger that will automatically fill up my sales history base after firing in ORDER table.
Your trigger is on the Order table, meaning SQL Server fires it after you insert records into the Order table. At which point, the relevant records in the Order_Details table couldn't have been inserted yet, because they have a foreign key to the Order table.
This is why an inner join between your inserted table and the Order_details table returns 0 rows.
If you want your sales_history from the order_details table, you have to populate it after you insert the records to the order_details table.
CREATE OR ALTER TRIGGER [dbo].[OrderDetails_AfterInsert]
ON [dbo].[ORDER_DETAILS]
AFTER INSERT
AS
INSERT INTO id.dbo.sales_history (id_order, id_item)
SELECT
inserted.ID_ORDER, inserted.ID_ITEM
FROM
inserted
INNER JOIN
[ORDER] ON [ORDER].ID_ORDER = inserted.ID_ORDER
WHERE [ORDER].ID_TYPE = 1 -- specific order type
As a side note: InsertTrig is bad name. Note the name of the trigger in my answer - it tells you exactly what this trigger is for, and on what table.

How to set trigger based on update query in SQL Server?

I am trying to set trigger whenever phone is updated in table1 and then do operation like check phone from table2 and if present, pick up the employee code from table2 and then update employee code in table1.
My code for trigger:
CREATE TRIGGER UPDATED_Contact_Trigger
ON table1
AFTER UPDATE
AS
DECLARE #tuid bigint;
DECLARE #phone varchar(15);
DECLARE #employee_code varchar(10);
IF (UPDATE (phone)) --Phone is the Column Name
BEGIN
SELECT #employee_code = i.emp_code
FROM table2 i (nolock)
WHERE i.MOBILE_NO = #phone
UPDATE table1
SET client_code = #employee_code
WHERE tuid= #tuid
END;
This trigger is set, but there is no update on table1 even if I update a contact which is present in table2
You're not even looking at the Inserted or Deleted pseudo tables in your code - how do you want to know what rows have been updated??
Inserted is a pseudo table that contains all updated rows - and it contains the new values after the update operation, while Deleted contains the same rows, but with the old values before the update.
You need to do something like this:
join your Table1 to Inserted to get the rows that were updated (since you didn't show your table structure, I cannot know what your primary key on Table1 is - you need to use that to join to Inserted)
add a join to your Table2 and pick those rows that have been updated, and limit those to the ones that have been updated in the Phone column (by comparing the Inserted.Phone value to Deleted.Phone)
Try this code:
CREATE TRIGGER UPDATED_Contact_Trigger
ON table1
AFTER UPDATE
AS
BEGIN
-- update your base table
UPDATE t1
-- set the client_code to the employee_code from Table2
SET client_code = t2.employee_code
FROM dbo.Table1 t1
-- join to "Inserted" to know what rows were updated - use the primary key
INNER JOIN Inserted i ON t1.(primarykey) = i.(primarykey)
-- join to "Deleted" to check if the "Phone" has been updated (between Deleted and Inserted)
INNER JOIN Deleted d ON i.(primarykey) = d.(primarykey)
-- join to "Table2" to be able to fetch the employee_code
INNER JOIN dbo.Table2 t2 ON t2.mobile_no = t1.phone
-- ensure the "Phone" has changed, between the old values (Deleted) and new values (Inserted)
WHERE i.Phone <> d.Phone;
END;

Trigger for update table after update records in another table?

I need a trigger for update field on Table_2 when over any fields are Updated on table_1. I created one but when I update one record in table_1 on Table_2 it’s updating all fields.
Sample SQL:-
Create trigger trigger-1 ON Table_1 After Update
As
begin
SET NOCOUNT ON;
Insert into table_2 (Col1,col2,col3,..etc) Select (ins.column names)
from table_1
Suppose table_1 has many fields but still I need Updated fields. How to get only updated fields from table_1 to table_2 by using trigger?
Your syntax is wrong. You can use the inserted table. It contains all the column of the base table
INSERT INTO table_2 ( col1, col2, col3, . . .)
SELECT i.cola, i.colb, i.colc, . . .
FROM inserted i
if you need to know which columns are updated, use UPDATE( column name )
https://learn.microsoft.com/en-us/sql/t-sql/functions/update-trigger-functions-transact-sql
Finally, I found perfect answer.
In the case of an UPDATE, the
Deleted table will contain the old values, while the Inserted table
contains the new values after Update.
Based on requirement, if we want to all fields in trigger we need to mention all fields in the table and write something like:
For records after UPDATE:
CREATE TRIGGER trg_ProdUpdate
ON dbo.Production
AFTER UPDATE
AS
Begin
INSERT INTO dbo.Attribiute (ID, attributeValue, attributetype)
SELECT i.ID, i.prodrecord, i.prodvalue
FROM Production i
INNER JOIN INSERTED d ON i.ID = d.ID
For Records before UPDATE:
CREATE TRIGGER trg_ProdUpdate
ON dbo.Production
AFTER UPDATE
AS
Begin
INSERT INTO dbo.Attribiute (ID, attributeValue, attributetype)
SELECT i.ID, i.prodrecord, i.prodvalue
FROM Attribiute i
INNER JOIN DELETED d ON i.ID = d.ID
We can join the Inserted and Deleted in to some History tables for audit by grabbing the Identical field (which is the same in both cases). The old value from the Deleted table, the new value from the Inserted table, and you store everything in the separate Table
For better understanding check this link Trigger insert old values- values that was updated

How to insert records from one table to other when multirow inserted in table using trigger?

I have 2 tables:
Table 1 and Table 2.
What i want to do, i want copy newly inserted records from Table1 to Table2 using trigger.
I created trigger on Table1, when bulk of data inserted in table1 it will copy newly inserted records in Table2. It work for single row insertion but not for multi row insertion.
Please let me know,what is wrong in that?
CREATE TRIGGER [dbo].[TRIG_TABLE1]
ON [dbo].[Table1]
AFTER INSERT AS
IF ##ROWCOUNT >=1
BEGIN
INSERT INTO Table2
(CustID
,DateCreated
,DateModify)
SELECT i.CustID
,i.DateCreated
,i.DateModify
FROM Table1 as i
WHERE (i.CustID IN (select CustID from INSERTED) and i.DateCreated IN (select DateCreated from INSERTED))
I don't get why aren't you using the INSERTED pseudo table directly:
CREATE TRIGGER [dbo].[TRIG_TABLE1]
ON [dbo].[Table1] AFTER INSERT AS
BEGIN
INSERT INTO Table2(CustID,DateCreated,DateModify)
SELECT CustID, DateCreated, DateModify
FROM INSERTED
END

If Exists in trigger

Is there a way I can check if a value exists in a table I want to insert into activated by a trigger? If the value does exist, I want nothing to be done and if it doesn't I would like it to be inserted.
This is my current trigger
ALTER TRIGGER [dbo].[Update]
On [dbo].[A]
AFTER UPDATE
AS
Declare #Id int;
SELECT #Id = Issue FROM Inserted
INSERT INTO dbo.[B] (id, problem)
SELECT BugId, ProjectID
FROM dbo.[C]
WHERE BugId = #Id and (projectid = 547)
Many thanks
inserted can contain multiple rows. And left join can be your friend for testing for whether rows already exist:
ALTER TRIGGER [dbo].[Update]
On [dbo].[A]
AFTER UPDATE
AS
INSERT INTO dbo.[B] (id, problem)
SELECT BugId, ProjectID
FROM
dbo.[C]
inner join
inserted i
on
c.BugID = i.Issue
left join
dbo.B
on
B.ID = c.BugID
WHERE
C.projectid = 547 and B.BugID is null
You should do it as described in this SO post. Use an IF statement to check the existence.

Resources