【问题标题】:SQL: Why does a CREATE TRIGGER need to be preceded by GOSQL:为什么 CREATE TRIGGER 需要在前面加上 GO
【发布时间】:2012-02-23 10:52:08
【问题描述】:

在创建 SQL 脚本以在表上创建触发器时,我想在创建触发器之前检查该触发器是否不存在。否则脚本无法多次运行。

所以我添加了一条语句,首先检查触发器是否存在。添加该语句后,CREATE TRIGGER 语句不再起作用。

IF NOT EXISTS (SELECT name FROM sysobjects
               WHERE name = 'tr_MyTable1_INSERT' AND type = 'TR')
BEGIN
    CREATE TRIGGER tr_MyTable1_INSERT
        ON MyTable1
        AFTER INSERT
    AS
    BEGIN
        ...
    END
END
GO

这给出了:

Msg 156, Level 15, State 1, Line 5
Incorrect syntax near the keyword 'TRIGGER'.

解决方案是删除现有触发器,然后创建新触发器:

IF EXISTS (SELECT name FROM sysobjects
           WHERE name = 'tr_MyTable1_INSERT' AND type = 'TR')
    DROP TRIGGER tr_MyTable1_INSERT
GO
CREATE TRIGGER tr_MyTable1_INSERT
    ON MyTable1
    AFTER INSERT
AS
BEGIN
    ...
END
GO

我的问题是:为什么第一个示例失败了?检查触发器存在有什么问题?

【问题讨论】:

    标签: sql sql-server triggers


    【解决方案1】:

    Certain statements need to be the first in a batch(如,由 GO 分隔的语句组)。

    引用:

    CREATE DEFAULT、CREATE FUNCTION、CREATE PROCEDURE、CREATE RULE、CREATE SCHEMA、CREATE TRIGGER 和 CREATE VIEW 语句不能与批处理中的其他语句组合。 CREATE 语句必须启动批处理。该批处理中的所有其他语句都将被解释为第一个 CREATE 语句定义的一部分。

    【讨论】:

      【解决方案2】:

      这只是 SQL Server 批处理的规则之一(参见):

      http://msdn.microsoft.com/en-us/library/ms175502.aspx

      否则,您可以更改一个对象,例如一个表,然后在实际进行更改之前参考同一批中的更改。

      【讨论】:

      • drop 会出现与 create 相同的问题吗?
      【解决方案3】:

      架构更改应该始终是单独的批处理调用...我猜他们这样做是为了保证您的 SELECT 会成功,如果您在同一批次中修改架构,他们可能无法保证这一点。只是猜测...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-03
        • 2019-02-20
        • 2013-04-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-15
        • 2015-08-19
        相关资源
        最近更新 更多