web-dev-qa-db-fra.com

insérer/supprimer/mettre à jour le déclencheur dans le serveur SQL

J'essaie de produire un déclencheur tout-en-un supprimer/insérer/mettre à jour. J'obtiens deux "syntaxe incorrecte près APRÈS aux deuxième et troisième APRES et une erreur de syntaxe près de la dernière FIN.

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

Si tout va bien, ceci est assez d'information. Je pense que le problème est ma syntaxe mais je ne trouve pas la syntaxe correcte en ligne.

18
user963070

le je vous donne est le code pour le déclencheur pour INSERT, UPDATE et DELETE cela fonctionne très bien sur Microsoft SQL Server 2008 et les versions ultérieures.

/* 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
54
Vishnu

Pas possible, par MSDN :

Le code same peut être exécuté pour plusieurs types de déclencheurs, mais la syntaxe ne permet pas la création de plusieurs blocs de code dans un même déclencheur:

Déclenchement d'une instruction INSERT, UPDATE ou DELETE dans une table ou une vue (déclencheur DML)

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 [ ; ] > }
10
D Stanley

Je l'utilise pour tous les statuts (mise à jour, insertion et suppression)

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
5
Ergin Çelik

Je suis d'accord avec la réponse de @ Vishnu. Je voudrais ajouter que si vous souhaitez utiliser l'utilisateur de l'application dans votre déclencheur, vous pouvez utiliser "context_info" pour transmettre les informations au déclencheur.

J'ai trouvé cela très utile par la suite: http://jasondentler.com/blog/2010/01/exploiting-context_info-for-fun-and-audit

0
Paul Trzyna