USE [ddb]
GO
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [dbo].[requeststrigger]
ON [dbo].[requests]
AFTER INSERT,UPDATE
AS
BEGIN
DECLARE @email VARCHAR(400);
DECLARE @firstname VARCHAR(400);
DECLARE @requestno VARCHAR(400);
DECLARE @lastname VARCHAR(400);
DECLARE @statusid INT;
DECLARE thecursor CURSOR FOR SELECT inserted.requestno,contacts.firstname,contacts.lastname,contacts.email FROM request_contacts,contacts,inserted WHERE request_contacts.requestid=inserted.requestid AND contacts.contactid=request_contacts.contactid AND request_contacts.notification=1 AND contacts.notification=1;
SET @statusid = (SELECT statusid FROM inserted);
IF @statusid = 4 AND @statusid <> (SELECT statusid FROM deleted)
BEGIN
SET NOCOUNT ON
SET ARITHABORT ON
OPEN thecursor;
FETCH NEXT FROM thecursor
INTO @requestno,@firstname,@lastname,@email
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC MAIL_SEND @email,@firstname,@requestno,@lastname;
FETCH NEXT FROM thecursor
INTO @requestno,@firstname,@lastname,@email
END
CLOSE thecursor;
DEALLOCATE thecursor
SET NOCOUNT OFF
END
END
这只会使整个UPDATE / INSERT不起作用。当我删除游标声明时,它的工作原理。光标只是从一个表中选择一个字段,该表存在于名为“contacts”的同一个数据库中。有什么问题?
答案 0 :(得分:2)
您是否准备考虑修改您的设计?你在这里尝试的东西似乎有几个问题。
触发器不一定是进行这种逐行操作的最佳位置,因为它与源表的更改一致地执行,并且会对系统的性能产生负面影响。
此外,您现有的代码仅对批处理中的单行评估statusid
,但从逻辑上讲,它可以在一批更新中设置为多个值。
更强大的方法可能是将应生成MAIL_SEND
操作的行插入到排队表中,计划作业可以从中挑选行并执行MAIL_SEND
,设置标志以便每项操作只进行一次。
这会简化你对插入的触发器 - 那里不需要游标(尽管在sechduled作业中你仍然需要某种循环)。