1

I am trying to dynamically create a number of triggers across two databases but I am having problems with the Create Trigger statement when switching databases

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)

If I run this statement I get the following issue

Error 8197, Level 16, State 4, Procedure tblBuild_DataPlate_DELTATrigger, Line 1
Message: The object 'dbo.tblBuild_DataPlate' does not exist or is invalid for this operation.

Changing the dynamic create trigger to include the USE statement does not work as the Create Trigger has to be the first statement

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.

You can not fully qualify the object with the database in this case as you get the following error

Error 166, Level 15, State 1, Procedure -, Line 1,
Message: 'CREATE/ALTER TRIGGER' does not allow specifying the database name as a prefix to the object name.

Is there a dynamic way around this?

4

1 に答える 1

3

以下のこのコードはsp_executesql、選択したデータベース (@DB) で実行されるため、これを使用して適切な場所にトリガーを作成できます。

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)
于 2012-11-29T09:28:57.593 に答える