SQL:为什么CREATE TRIGGER需要以GO开头

时间:2012-01-31 17:43:13

标签: sql sql-server triggers

在创建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

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

3 个答案:

答案 0 :(得分:11)

Certain statements need to be the first in a batch(如GO分隔的一组陈述)。

引用:

  

创建默认,创建功能,创建过程,创建规则,创建模式,创建触发器和创建视图语句不能与批处理中的其他语句组合。 CREATE语句必须启动批处理。该批次中的所有其他语句将被解释为第一个CREATE语句定义的一部分。

答案 1 :(得分:1)

它只是SQL Server批处理的一个规则(请参阅参考资料):

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

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

答案 2 :(得分:1)

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