user963070
user963070

Reputation: 639

insert/delete/update trigger in SQL server

I am trying to produce an all-in-one delete/insert/update trigger. I get two "incorrect syntax near AFTER at the second and third AFTERS and a syntax error near the last END.

CREATE TRIGGER trig_all_dml
 ON [dbo.file]
 AFTER UPDATE
 AS BEGIN
    UPDATE 
           (excess code)       
 END

 AFTER INSERT
 AS BEGIN
     UPDATE 
             (excess code)
  END

 AFTER DELETE
 AS BEGIN
    UPDATE (excess code)

  END
  GO

Hopefully, this is enough information. I think the problem is my syntax but I can't find the correct syntax online.

Upvotes: 33

Views: 166685

Answers (5)

goktemkirez
goktemkirez

Reputation: 1

I used Northwind DB and :

ALTER TRIGGER Update_StockQuantity ON dbo.[Order Details] 
AFTER INSERT, UPDATE, DELETE 
AS 
BEGIN 
    declare @productId int
    declare @quantity smallint
    declare @quantityBefore smallint

    --Read Table Before Update
    SELECT ProductID, ProductName, UnitsInStock FROM Products WHERE ProductID = @productId

    -- UPDATE
    IF EXISTS (SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted)
    BEGIN
        SELECT @productId=ProductID, @quantity=Quantity FROM inserted
        SELECT @quantityBefore=Quantity FROM deleted

        UPDATE Products SET UnitsInStock = UnitsInStock - @quantity + @quantityBefore WHERE ProductID = @productId
    END

    -- INSERT
    IF EXISTS (SELECT * FROM inserted) AND NOT EXISTS(SELECT * FROM deleted)
    BEGIN
        SELECT @productId=ProductID, @quantity=Quantity FROM inserted

        UPDATE Products SET UnitsInStock = UnitsInStock - @quantity WHERE ProductID = @productId
    END

    -- DELETE
    IF EXISTS (SELECT * FROM deleted) AND NOT EXISTS(SELECT * FROM inserted)
    BEGIN
        SELECT @productId=ProductID, @quantity=Quantity FROM deleted

        UPDATE Products SET UnitsInStock = UnitsInStock + @quantity WHERE ProductID = @productId
    END

    --Read Table After Update
    SELECT ProductID, ProductName, UnitsInStock FROM Products WHERE ProductID = @productId

END

Upvotes: 0

Ergin Çelik
Ergin Çelik

Reputation: 775

I use that for all status (update, insert and delete)

CREATE TRIGGER trg_Insert_Test
ON [dbo].[MyTable]
AFTER UPDATE, INSERT, DELETE 
AS
BEGIN
SET NOCOUNT ON;

DECLARE @Activity  NVARCHAR (50)

-- update
IF EXISTS (SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted)
BEGIN
    SET @Activity = 'UPDATE'
END

-- insert
IF EXISTS (SELECT * FROM inserted) AND NOT EXISTS(SELECT * FROM deleted)
BEGIN
    SET @Activity = 'INSERT'
END

-- delete
IF EXISTS (SELECT * FROM deleted) AND NOT EXISTS(SELECT * FROM inserted)
BEGIN
    SET @Activity = 'DELETE'
END



-- delete temp table
IF OBJECT_ID('tempdb..#tmpTbl') IS NOT NULL DROP TABLE #tmpTbl

-- get last 1 row
SELECT * INTO #tmpTbl FROM (SELECT TOP 1 * FROM (SELECT * FROM inserted
                                                 UNION 
                                                 SELECT * FROM deleted
                                                 ) AS A ORDER BY A.Date DESC
                            ) AS T


-- try catch
BEGIN TRY 

    INSERT INTO MyTable  (
           [Code]
          ,[Name]
           .....
          ,[Activity])
    SELECT [Code]
          ,[Name]
          ,@Activity 
    FROM #tmpTbl

END TRY BEGIN CATCH END CATCH


-- delete temp table
IF OBJECT_ID('tempdb..#tmpTbl') IS NOT NULL DROP TABLE #tmpTbl

SET NOCOUNT OFF;
END

Upvotes: 12

D Stanley
D Stanley

Reputation: 152501

Not possible, per MSDN:

You can have the same code execute for multiple trigger types, but the syntax does not allow for multiple code blocks in one trigger:

Trigger on an INSERT, UPDATE, or DELETE statement to a table or view (DML Trigger)

CREATE TRIGGER [ schema_name . ]trigger_name 
ON { table | view } 
[ WITH <dml_trigger_option> [ ,...n ] ]
{ FOR | AFTER | INSTEAD OF } 
{ [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ] } 
[ NOT FOR REPLICATION ] 
AS { sql_statement  [ ; ] [ ,...n ] | EXTERNAL NAME <method specifier [ ; ] > }

Upvotes: 11

Paul A. Trzyna
Paul A. Trzyna

Reputation: 300

I agree with @Vishnu's answer. I would like to add that if you want to use the application user in your trigger you can use "context_info" to pass the info to the trigger.

I found following very helpful in doing that: http://jasondentler.com/blog/2010/01/exploiting-context_info-for-fun-and-audit

Upvotes: 0

Vishnu
Vishnu

Reputation: 892

the am giving you is the code for trigger for INSERT, UPDATE and DELETE this works fine on Microsoft SQL SERVER 2008 and onwards database i am using is Northwind

/* comment section first create a table to keep track of Insert, Delete, Update
create table Emp_Audit(
                    EmpID int,
                    Activity varchar(20),
                    DoneBy varchar(50),
                    Date_Time datetime NOT NULL DEFAULT GETDATE()
                   );

select * from Emp_Audit*/

create trigger Employee_trigger
on Employees
after UPDATE, INSERT, DELETE
as
declare @EmpID int,@user varchar(20), @activity varchar(20);
if exists(SELECT * from inserted) and exists (SELECT * from deleted)
begin
    SET @activity = 'UPDATE';
    SET @user = SYSTEM_USER;
    SELECT @EmpID = EmployeeID from inserted i;
    INSERT into Emp_Audit(EmpID,Activity, DoneBy) values (@EmpID,@activity,@user);
end

If exists (Select * from inserted) and not exists(Select * from deleted)
begin
    SET @activity = 'INSERT';
    SET @user = SYSTEM_USER;
    SELECT @EmpID = EmployeeID from inserted i;
    INSERT into Emp_Audit(EmpID,Activity, DoneBy) values(@EmpID,@activity,@user);
end

If exists(select * from deleted) and not exists(Select * from inserted)
begin 
    SET @activity = 'DELETE';
    SET @user = SYSTEM_USER;
    SELECT @EmpID = EmployeeID from deleted i;
    INSERT into Emp_Audit(EmpID,Activity, DoneBy) values(@EmpID,@activity,@user);
end

Upvotes: 86

Related Questions