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.
我正在尝试生成一体化删除/插入/更新触发器。在第二次和第三次AFTERS后,我得到两个“AFTER附近的语法错误,并且在最后一个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.
希望这是足够的信息。我认为问题是我的语法,但我无法在线找到正确的语法。
4 个解决方案
#1
43
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
我给你的是INSERT,UPDATE和DELETE触发器的代码,这在Microsoft SQL SERVER 2008和我正在使用的数据库上正常工作是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
#2
10
Not possible, per MSDN:
根据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)
触发对表或视图的INSERT,UPDATE或DELETE语句(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 [ ; ] > }
#3
5
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
#4
0
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.
我同意@ Vishnu的回答。我想补充一点,如果你想在你的触发器中使用应用程序用户,你可以使用“context_info”将信息传递给触发器。
I found following very helpful in doing that: http://jasondentler.com/blog/2010/01/exploiting-context_info-for-fun-and-audit
我发现以下内容非常有帮助:http://jasondentler.com/blog/2010/01/exploiting-context_info-for-fun-and-audit
#1
43
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
我给你的是INSERT,UPDATE和DELETE触发器的代码,这在Microsoft SQL SERVER 2008和我正在使用的数据库上正常工作是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
#2
10
Not possible, per MSDN:
根据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)
触发对表或视图的INSERT,UPDATE或DELETE语句(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 [ ; ] > }
#3
5
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
#4
0
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.
我同意@ Vishnu的回答。我想补充一点,如果你想在你的触发器中使用应用程序用户,你可以使用“context_info”将信息传递给触发器。
I found following very helpful in doing that: http://jasondentler.com/blog/2010/01/exploiting-context_info-for-fun-and-audit
我发现以下内容非常有帮助:http://jasondentler.com/blog/2010/01/exploiting-context_info-for-fun-and-audit