T-SQL 更新触发器
T-SQL Update Trigger
我试图在 SQL 服务器中创建以下触发器,但 SSMS 抛出一个错误,我不知道它是什么。有什么想法吗?
Msg 156, Level 15, State 1, Line 2
Incorrect syntax near the keyword 'trigger'.
代码:
IF NOT EXISTS(SELECT * FROM sys.triggers
WHERE object_id = OBJECT_ID(N'[dbo].[trAfterUpdateInfoDoc]'))
CREATE TRIGGER [dbo].[trAfterUpdateInfoDoc]
ON [dbo].[InfoDocs]
AFTER UPDATE
AS
BEGIN
DECLARE @infodoctemplateid INT;
DECLARE @infodocid INT;
DECLARE @requireccount FLOAT(2);
DECLARE @filledcount FLOAT(2);
DECLARE @pcnt FLOAT(2);
DECLARE c CURSOR FOR
SELECT id
FROM InfoDocs ifd
WHERE exists (SELECT 1 FROM Inserted AS i WHERE i.id = ifd.id)
OPEN c
FETCH NEXT FROM c INTO @infodocid
WHILE @@Fetch_Status = 0
BEGIN
SELECT @infodoctemplateid = InfoDocTemplateId
FROM InfoDocs
WHERE id = @infodocid;
SELECT @requireccount = COUNT(*)
FROM InfoDocTemplateFields
WHERE InfoDocTemplateId = @infodoctemplateid
AND IsRequired = 1;
IF (@requireccount = 0)
BEGIN
set @pcnt = 100;
END
ELSE
BEGIN
select @filledcount = count(*) from InfoDocFields
where InfoDocId = @infodocid
and InfoDocTemplateFieldId in (select id from InfoDocTemplateFields where InfoDocTemplateId = @infodoctemplateid and IsRequired = 1)
and (BooleanValue is not null or (StringValue is not null and StringValue <> '') or IntValue is not null or DateValue is not null)
set @pcnt = @filledcount / @requireccount * 100.0;
END
update InfoDocs set PercentageCompleted = @pcnt Where id = @infodocid;
Fetch next From c into @infodocid
End
Close c
Deallocate c
END
Create Trigger(限制部分)必须是批处理中的第一个语句,因此您不能在它之前使用 IF exists 检查。
在 SQL Server 2016 SP1 及更高版本中,您可以使用 CREATE OR ALTER TRIGGER... 实现相同的行为。
Pre-SQL Server 2016 SP1,有一些建议
我也支持 Zohar 的评论,即把这个逻辑放入触发器中很可能会导致您出现许多性能问题,并且可能难以追踪意外 behaviour/bugs。
任何时候创建像触发器这样的 SQL 对象时,它必须是批处理中创建的唯一对象。批处理由关键字 GO
.
终止
尝试重构您的代码以适应这个通用结构,看看它是否有效:
IF OBJECT_ID(N'[dbo].[trAfterUpdateInfoDoc]') IS NOT NULL
DROP TRIGGER [dbo].[trAfterUpdateInfoDoc]
GO
CREATE TRIGGER [dbo].[trAfterUpdateInfoDoc]
ON [dbo].[InfoDocs]
AFTER UPDATE
AS
BEGIN
--PLACE CODE HERE
END
GO
我试图在 SQL 服务器中创建以下触发器,但 SSMS 抛出一个错误,我不知道它是什么。有什么想法吗?
Msg 156, Level 15, State 1, Line 2
Incorrect syntax near the keyword 'trigger'.
代码:
IF NOT EXISTS(SELECT * FROM sys.triggers
WHERE object_id = OBJECT_ID(N'[dbo].[trAfterUpdateInfoDoc]'))
CREATE TRIGGER [dbo].[trAfterUpdateInfoDoc]
ON [dbo].[InfoDocs]
AFTER UPDATE
AS
BEGIN
DECLARE @infodoctemplateid INT;
DECLARE @infodocid INT;
DECLARE @requireccount FLOAT(2);
DECLARE @filledcount FLOAT(2);
DECLARE @pcnt FLOAT(2);
DECLARE c CURSOR FOR
SELECT id
FROM InfoDocs ifd
WHERE exists (SELECT 1 FROM Inserted AS i WHERE i.id = ifd.id)
OPEN c
FETCH NEXT FROM c INTO @infodocid
WHILE @@Fetch_Status = 0
BEGIN
SELECT @infodoctemplateid = InfoDocTemplateId
FROM InfoDocs
WHERE id = @infodocid;
SELECT @requireccount = COUNT(*)
FROM InfoDocTemplateFields
WHERE InfoDocTemplateId = @infodoctemplateid
AND IsRequired = 1;
IF (@requireccount = 0)
BEGIN
set @pcnt = 100;
END
ELSE
BEGIN
select @filledcount = count(*) from InfoDocFields
where InfoDocId = @infodocid
and InfoDocTemplateFieldId in (select id from InfoDocTemplateFields where InfoDocTemplateId = @infodoctemplateid and IsRequired = 1)
and (BooleanValue is not null or (StringValue is not null and StringValue <> '') or IntValue is not null or DateValue is not null)
set @pcnt = @filledcount / @requireccount * 100.0;
END
update InfoDocs set PercentageCompleted = @pcnt Where id = @infodocid;
Fetch next From c into @infodocid
End
Close c
Deallocate c
END
Create Trigger(限制部分)必须是批处理中的第一个语句,因此您不能在它之前使用 IF exists 检查。
在 SQL Server 2016 SP1 及更高版本中,您可以使用 CREATE OR ALTER TRIGGER... 实现相同的行为。
Pre-SQL Server 2016 SP1,有一些建议
我也支持 Zohar 的评论,即把这个逻辑放入触发器中很可能会导致您出现许多性能问题,并且可能难以追踪意外 behaviour/bugs。
任何时候创建像触发器这样的 SQL 对象时,它必须是批处理中创建的唯一对象。批处理由关键字 GO
.
尝试重构您的代码以适应这个通用结构,看看它是否有效:
IF OBJECT_ID(N'[dbo].[trAfterUpdateInfoDoc]') IS NOT NULL
DROP TRIGGER [dbo].[trAfterUpdateInfoDoc]
GO
CREATE TRIGGER [dbo].[trAfterUpdateInfoDoc]
ON [dbo].[InfoDocs]
AFTER UPDATE
AS
BEGIN
--PLACE CODE HERE
END
GO