Sql-Server-2012

將數據庫從 SQL Server 2005 升級到 2012 發現語法錯誤

  • March 27, 2015

我最近從 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 上,它會拋出(我所期望的)語法錯誤。

語法錯誤:觸發器聲明中操作“更新”的重複規範。

為什麼這不會在 SQL Server 2005 上引發語法錯誤?我在這方面的 google-fu 讓我失望了。

為什麼這似乎適用於 SQL Server 2005?

該命令的實際語法表明沒有FOR UPDATE, UPDATE- 或者更確切地說它沒有任何意義:

CREATE TRIGGER [ schema_name . ]trigger_name 
ON { table | view } 
[ WITH <dml_trigger_option> [ ,...n ] ] 
{ FOR | AFTER | INSTEAD OF } 
{ [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ] } 
 AS { sql_statement  [ ; ] [ ,...n ] [ ; ] > }

因此,刪除第二個UPDATE(或將其更改為INSERT如果這是所需的功能)並且它不應該引發錯誤。此外,Aaron 對實際觸發內容的建議也是一個很好的修改。

我不知道它為什麼在 2005 年工作的具體細節,但在語法檢查方面,a 的要求似乎CREATE TRIGGER有點寬鬆。如果它不是一個記錄在案的 break,它不是,那麼除非你問 MS,否則很難說。

無論如何,它確實在我的測試 2005 實例中正常執行:

CREATE TABLE [dbo].[trigger_test] (
NAME nvarchar(50) NOT NULL,
counter INT NOT NULL )
GO

CREATE TRIGGER [dbo].[trigger] on [dbo].[trigger_test]
FOR UPDATE, UPDATE
AS
UPDATE [dbo].[trigger_test]
 set name = 'Greg', counter = counter + 1
GO

INSERT INTO [dbo].[trigger_test]  
VALUES ('Alice', 1)
GO

UPDATE [dbo].[trigger_test] 
SET name = 'John'
GO

SELECT * FROM [dbo].[trigger_test]
GO

結果Greg2作為結果。它可能是對觸發器的無害(在 2005 年),因為它根本不會更改最終值並且不會執行兩次更新。

引用自:https://dba.stackexchange.com/questions/96331