我最近从 SQL Server 2005 升级到 2012。但是在验证过程中,发现了一个错误。
某个触发器的编码如下:
CREATE TRIGGER [dbo].[trigger] on [dbo].[foo]
FOR UPDATE, UPDATE
AS
UPDATE foobar
SET datetime = GetDate()
FROM bar
WHERE foobar.id = bar.id
GO
我可以在 SQL Server 2005 上安全地(奇怪地)执行此操作。
但是在 SQL Server 2012 上它抛出(我所期望的)语法错误。
语法错误:触发器声明中操作“UPDATE”的重复规范。
为什么这不会在 SQL Server 2005 上引发语法错误?我在这方面的 google-fu 让我失望了。
为什么这似乎适用于 SQL Server 2005?
John 是对的,您得到更新后的语法错误消息:
这绝对是因为触发器被指定为
FOR UPDATE, UPDATE
. 这种语法在旧的兼容级别中是允许的,但在现代的兼容级别中是不允许的。事实上,我已经对此进行了测试,语法在 80 兼容模式(SQL Server 2000)中是允许的,但在 90+ 中则不允许。我已经更新了关于 compat level 80 的规范答案。
(至于为什么它不是一个记录在案的重大变化,好吧,耸耸肩。如果你想要一个有意义的答案,你需要直接联系微软。)
至于触发器本身,我会这样写:
语法错误可能是对单词的更严格的解析
table
,不确定。如果那确实是您的表的名称,您应该更改它,或者[put it in square brackets]
.命令的实际语法表明没有这样的东西
FOR UPDATE, UPDATE
——或者更确切地说,它只是没有任何意义:所以删除第二个
UPDATE
(或将其更改为INSERT
所需的功能)并且它不应该抛出错误。此外,Aaron 对实际触发内容的建议也是一个很好的修改。我不知道它为什么在 2005 年起作用的具体细节,但似乎 a
CREATE TRIGGER
在语法检查方面的要求在那时更为宽松。如果它不是一个记录的 break,它不是,那么除非你问 MS,否则很难说。无论如何,它在我的测试 2005 实例中确实能正常运行:
结果
Greg
和2
作为结果。它可能是对触发器的无害(2005 年)添加,因为它根本不会更改最终值并且不会执行两次更新。