1

我在 Microsoft SQL Server 中创建了一个更新触发器,如果​​日期连续更改,它会向我发送电子邮件。

与此类似:

IF UPDATE(ColumnName)
    BEGIN
        DECLARE @columnVal AS DATETIME

        SELECT 
            @columnVal = i.columnName
        FROM 
            inserted i JOIN deleted d on i.RowId= d.RowId;

        EXEC msdb.dbo.sp_send_dbmail
                @profile_name = 'me',
                @recipients = 'me@company.com',
                @body = 'blah blah datechange',
                @body_format = 'HTML',
                @subject = 'subject';
END

有一段时间效果很好。
然后我切换到批量更新,如果多行的日期发生变化,则只发送第一行电子邮件。我试图设置一个光标来滚动更改,但我无法让它工作,类似于下面:

DECLARE @columnVal AS DATETIME

DECLARE cur CURSOR LOCAL READ_ONLY FAST_FORWARD FOR
    SELECT
        i.ColumnName
    FROM 
    inserted i JOIN deleted d on i.RowId= d.RowId;

OPEN cur

FETCH NEXT FROM cur INTO @columnVal

WHILE @@FETCH_STATUS = 0
BEGIN
   IF UPDATE(ColumnName)
   BEGIN
        EXEC msdb.dbo.sp_send_dbmail
                @profile_name = 'me',
                @recipients = 'me@company.com',
                @body = 'blah blah datechange',
                @body_format = 'HTML',
                @subject = 'subject';
    END

    FETCH NEXT FROM cur INTO @columnVal
END

CLOSE cur
DEALLOCATE cur

关于如何完成这项任务的任何想法?Update(ColumnName) 函数甚至可以在游标内正常工作(它实际上会告诉我该列是否已针对该行进行了更新吗?)

4

1 回答 1

2

触发器内的光标是一个非常非常糟糕的主意。

触发器应该非常精简 - 它不应该做很多工作!我建议只“记下”您必须向谁发送电子邮件 - 但将电子邮件的实际发送留给单独的例如 SQL Server 代理作业,该作业不是触发器的一部分。

触发器经常被触发并且经常出乎意料 - 不要将处理负担放入其中!尤其是不像光标这样的性能杀手!

要查找您感兴趣的那些行,您可以使用WHERE类似以下的子句:

WHERE inserted.ColumnName <> deleted.ColumnName

UPDATE触发器的上下文中,这意味着 的新值ColumnName与旧值不同 --> 此列已更新。

于 2013-10-23T16:10:13.770 回答