Adding modify and delete to insert trigger - sql-server

I've been tasked with pushing records from one table (T1) to another (T2). I have the insert portion complete as follows:
CREATE TRIGGER [dbo].[CP_to_TW2]
ON [dbo].[TEST_PROJ]
FOR INSERT
AS
BEGIN
INSERT INTO dbo.TEST_TW (PROJECT_ID,PROJECT_DESC,PROJECT_MANAGER)
SELECT PROJ_ID,PROJ_ID+PROJ_NAME,PROJECT_MANAGER FROM inserted
END
TEST_PROJ is T1 and TEST_TW is T2. The PROJECT_ID and PROJ_ID columns store the unique IDs. The trigger fires correct and inserts corresponding rows into T2. However, I am unsure how to get modifications made to T1 to show in T2. For example, if the Project manager is updated in T1 it needs to also update in T2. In addition to this, I am unsure how to make that records in T2 are deleted when they are deleted in T1. Any help would be greatly appreciated.

You can create triggers also for delete or update ops, in update you have deleted table in addition to inserted
CREATE TRIGGER [dbo].[CP_to_TW2]
ON [dbo].[TEST_PROJ]
AFTER UPDATE
AS
BEGIN
UPDATE TEST_TW....
END
CREATE TRIGGER [dbo].[CP_to_TW2]
ON [dbo].[TEST_PROJ]
AFTER DELETE
AS
BEGIN
DELETE FROM dbo.TEST_TW (PROJECT_ID,PROJECT_DESC,PROJECT_MANAGER)
WHERE xxx in (SELECT xxx FROM deleted)
END

Related

How to write trigger body in SQL Server

I'm confused how a trigger in SQL Server knows what event fired the trigger and what to do.
For example I have a trigger that update on table A and it is performing AFTER INSERT, DELETE, UPDATE. Now my question is how I make the body to perform each task when it triggered, do I need to make separate triggers for each task or is it a way to specify what it needs to do for each task on a single body and a single trigger. And if it is okay can anybody give some explanation and example for it
Thanks
If you really must do a single trigger - this is the logic needed to keep the three operation - INSERT, UPDATE and DELETE - apart:
CREATE TRIGGER dbo.YourTriggerName
ON dbo.YourTable
AFTER DELETE, INSERT, UPDATE
AS
BEGIN
-- check if both the Inserted as well as the Deleted pseudo tables exist
IF EXISTS (SELECT * FROM Inserted) AND EXISTS (SELECT * FROM Deleted)
BEGIN
-- trigger operation : UPDATE
-- "Inserted" contains the new values for the rows after the update
-- "Deleted" contains the old values for the rows before the update
END
-- check if only the Inserted pseudo tables exists
IF EXISTS (SELECT * FROM Inserted) AND NOT EXISTS (SELECT * FROM Deleted)
BEGIN
-- trigger operation: INSERT
-- "Inserted" contains the values for the rows inserted
END
-- check if only the Deleted pseudo tables exists
IF NOT EXISTS (SELECT * FROM Inserted) AND EXISTS (SELECT * FROM Deleted)
BEGIN
-- trigger operation: DELETE
-- "Deleted" contains the values for the rows having been deleted
END
END;
BE AWARE: the trigger is called once per statement - not once per row - so the Inserted and Deleted pseudo tables will potentially contain multiple rows - handle them in a set-based manner, as tables - don't do anything like
SELECT #ID = i.ID FROM Inserted i
This will NOT WORK for multiple rows being inserted at once in a single SQL statement!
But as I said - this is a bit messy, makes for a really large trigger, and makes it hard to maintain this code. I'd personally would much rather have three separate, focused triggers - one for each of the operations you need to handle.

SQL Server trigger (before insert) to validate data?

We have an application that we use in the warehouse to track which pickers are picking which orders. We have an instance every so often where the the order number that is inserted into the table is not the actual order number. While we are going to put in some validation on the application, I was wondering how we could put a trigger in place on the Table to prevent writing the record when the order number is wrong.
For example:
Before insert, when len(ordernum) <> '6' then delete record.
else insert into Table1
?
INSTEAD OF triggers cause their source DML operation to skip and they just execute the code provided inside them. Actual insert, delete or update operation do not occur at all. However they have their associated inserted and deleted tables simulating the DML operation. Inserted and deleted tables are widely used in operations inside triggers
--Instead of Trigger
CREATE TRIGGER BeforeDelete_Trigger ON [dbo].[Order1]
INSTEAD OF INSERT AS
BEGIN
IF (SELECT * FROM Order1 WHERE len(ordernum) <> '6')
THEN
INSERT INTO Order1;
ELSE
INSERT INTO Order2 (col 1, col 2) VALUES (inserted.col1, inserted.col2);
END;
GO
you can create an instead of trigger:
--Create an INSTEAD OF INSERT trigger on the table:
CREATE TRIGGER InsteadTrigger on dbo.table1
INSTEAD OF INSERT
AS
BEGIN
if len(inserted.ordernum)= 6
insert into table1 (ordernum,col1, col2) values (inserted.ordernum,inserted.col1, inserted.col2)
--rows that dont have a ordernum length of 6 are not inserted
end

SQL Change in one table automatically change the other table

I am new to Database and in SQL also. I have two tables t1 and t2. There is a "name" column in t1 and t2 tables. Here t1. name will be given by me, but I want that t2. name automatically change on the basis of t1. id=t2. id please help me by giving SQL query for it. Also tells me "is, stored procedures or triggers required for this?" If yes, then how I will use them? Thanks in advance..... :-)
CREATE TRIGGER [dbo].[trg_Table2]
ON [dbo].[table1] AFTER UPDATE
AS
BEGIN
IF UPDATE (name)
BEGIN
INSERT INTO table2 (name)
SELECT d.name FROM DELETED d
END
END
I provided you an idea. Use it for updating the record. Here 'Deleted' table is the one where the data changed in table1 which can be used to store that previous data into other table that you want. I inserted the data, you update it now.
Sorry, I just saw it, you want the current data then use the 'INSERTED' table just like the 'DELETED'.

How do I make a trigger that only affects the row that was updated/inserted?

I have a table with two columns where I need one (columnB) to be a copy of the other one (columnA). So, if a row is inserted or updated, I want the value from columnA to be copied to columnB.
Here's what I have now:
CREATE TRIGGER tUpdateColB
ON products
FOR INSERT, UPDATE AS
BEGIN
UPDATE table
SET columnB = columnA
END
The problem now is that the query affects all rows, not just the one that was updated or inserted. How would I go about fixing that?
Assuming you have a primary key column, id, (and you should have a primary key), join to the inserted table (making the trigger capable of handling multiple rows):
CREATE TRIGGER tUpdateColB
ON products
FOR INSERT, UPDATE AS
BEGIN
UPDATE table
SET t.columnB = i.columnA
FROM table t INNER JOIN inserted i ON t.id = i.id
END
But if ColumnB is always a copy of ColumnA, why not create a Computed column instead?
Using the inserted and deleted Tables
There is a special inserted table available in triggers that will contain the "after" version of rows impacted by an INSERT or UPDATE operation. Similarly, there is a deleted table that will contain the "before" version of rows impacted by an UPDATE or DELETE operation.
So, for your specific case:
UPDATE t
SET t.columnB = t.columnA
FROM inserted i
INNER JOIN table t
ON i.PrimaryKeyColumn = t.PrimaryKeyColumn

updating multiple tables with triggers - SQL Server

I need to update my tableA based on the insertions in tableB. i have created a trigger which fires when a row is inserted into tableB and simply copies it to tableA (which is exactly what i want). But the problem comes when i update my existing records in tableB, the rows in tableA already exist with the same primary key.
to deal with it, i tried to delete the existing row in tableA where the primary key matches for the updated row and then simply insert the row from the "inserted" table. But, tsql simply does not let me delete me from a trigger and gives an error stating "The multi-part identifier "INSERTED.Id" could not be bound."
Here is what i am trying to accomplish code-wise:
delete from dbo.CurrentItems where dbo.CurrentItems.CurrentItemId = INSERTED.Id
INSERT INTO CurrentItems
SELECT * FROM INSERTED
WHERE IsActive = 1
Any ideas guys?
In the DELETE FROM statement, you have to add the INSERTED pseudo-table to the tables you're operating on (in the FROM clause), like so:
DELETE dbo.CurrentItems
FROM dbo.CurrentItems
, INSERTED
WHERE dbo.CurrentItems.CurrentItemId = INSERTED.Id
INSERT INTO CurrentItems
SELECT * FROM INSERTED
WHERE IsActive = 1
Alternatively, you could use an INNER JOIN:
DELETE dbo.CurrentItems
FROM dbo.CurrentItems CI
INNER JOIN INSERTED I ON CI.CurrentItemId = I.Id
Why can't you just simply update the existing rows in TableA when your rows in TableB get updated?? UPDATE instead of DELETE/INSERT.
You could have a AFTER INSERT trigger which does what you want now, plus an AFTER UPDATE trigger which would be updating rows in TableA (instead of inserting new ones).
You said you have a trigger that fires when "a row is inserted into tableB". So you have the trigger to fire on Inserts. It sounds to me like you also have the trigger to fire on Updates as well. Did you want the trigger to fire on updates as well? If not, remove "Update" from the trigger definition.
Randy

Resources