动态,跨数据库触发器创建

时间:2012-11-29 09:11:46

标签: sql sql-server tsql sql-server-2005

我试图在两个数据库中动态创建多个触发器但是在切换数据库时我遇到了Create Trigger语句的问题

SET @SQL = 'SELECT Name FROM ' + @DB + '.sys.triggers WHERE Name = ' + '''' 
           + @Table + '_DELTATrigger' + ''''
EXEC(@SQL)

IF @@RowCount > 0   
BEGIN
  SET @SQL = 'USE ' + @DB + '; DROP TRIGGER [dbo].[' + @Table + '_DELTATrigger]'
  EXEC(@SQL)
END

SET @SQL = 'CREATE TRIGGER [dbo].[' + @Table + '_DELTATrigger] 
                ON [dbo].[' + @Table + '] 
                AFTER INSERT, UPDATE 
                AS 
                BEGIN 
                  SET NOCOUNT ON 
                  UPDATE [' + @Table + '] 
                  SET [Delta] = 1 
                  FROM inserted 
                  WHERE inserted.[ID] = [' + @Table + '].[ID] 
                END;'               
EXEC (@SQL)

如果我运行此声明,我会遇到以下问题

  

错误8197,等级16,状态4,程序tblBuild_DataPlate_DELTATrigger,第1行
  消息:对象'dbo.tblBuild_DataPlate'不存在或是   此操作无效。

更改动态创建触发器以包含USE语句不起作用,因为创建触发器必须是第一个语句

SET @SQL = 'USE ' + @DB + '; CREATE TRIGGER [dbo].[' + @Table + '_DELTATrigger]
            ON [dbo].[' + @Table + '] 
            AFTER INSERT, UPDATE 
            AS 
            BEGIN 
              SET NOCOUNT ON 
              UPDATE [' + @Table + '] 
              SET [Delta] = 1 
              FROM inserted 
              WHERE inserted.[ID] = [' + @Table + '].[ID] 
            END;'               
EXEC (@SQL)

Error 111, Level 15, State 1, Procedure -, 
Line 1, Message: 'CREATE TRIGGER' must be the first 
statement in a query batch.

在这种情况下,您无法使用数据库完全限定对象,因为您收到以下错误

  

错误166,等级15,状态1,过程 - ,行1,
  消息:'CREATE / ALTER TRIGGER'不允许   将数据库名称指定为对象名称的前缀。

有没有一种动态的解决方法?

1 个答案:

答案 0 :(得分:3)

下面的代码将在所选数据库(@DB)上运行sp_executesql,因此,您可以在rigth位置创建触发器:

SET @SQL = 'EXEC ' + @DB + '..sp_executesql N''
CREATE TRIGGER [dbo].[' + @Table + '_DELTATrigger] 
                            ON [dbo].[' + @Table + '] 
                            AFTER INSERT, UPDATE 
                        AS 
                        BEGIN 
                            SET NOCOUNT ON 

                        END;'''               
            EXEC (@SQL)