SQL Server 2014 Создать триггер DDL на Create Table, который создает триггер для таблицы - PullRequest
0 голосов
/ 23 мая 2018

Я работаю со сторонним инструментом, который создает базы данных и таблицы.Я хотел бы триггер на одной из тех таблиц, которые создаются.Я думал, что попробую создать серверный триггер DDL, который срабатывает при создании таблицы в новой базе данных, что, в свою очередь, создает триггер для этой таблицы.Я не могу добавить триггер в базу данных «модель», потому что эта таблица создается с помощью инструмента динамически.

Я пробовал следующее:

CREATE TRIGGER ddl_trig_createTable   
ON ALL SERVER   
FOR CREATE_TABLE   
AS   
    DECLARE @databaseName varchar(255)
    DECLARE @AffectedTables varchar(255) 
    SELECT  @AffectedTables = EVENTDATA().value('(/EVENT_INSTANCE/ObjectName)[1]','nvarchar(100)') 
    IF (@AffectedTables IN ('DynamicallyCreatedTable'))
    BEGIN

        select @databaseName = CAST(eventdata().query('/EVENT_INSTANCE/DatabaseName[1]/text()') as NVarchar(128))

        EXEC('CREATE TRIGGER ' + @databaseName + '.[dbo].[tgrDynamicTableTrigger]
              ON
                ' + @databaseName + '.[dbo].[DynamicallyCreatedTable]
              AFTER UPDATE
              AS
              BEGIN
                SET NOCOUNT ON
                -- trigger code here
              END')
    END
GO 

, которая выдает следующую ошибку при создании таблицы:

Сообщение 166, Уровень 15, Состояние 1Строка 1 'CREATE / ALTER TRIGGER' не позволяет указывать имя базы данных в качестве префикса к имени объекта.

Я попытался изменить динамический sql, заменив полное имя таблицы, чтобы попытаться "используйте 'оператор:

--- 8< ---
    EXEC('use ' + @databaseName + '
          CREATE TRIGGER [dbo].[tgrDynamicTableTrigger]
          ON
--- 8< ---

Однако при создании таблицы возникла следующая ошибка:

Сообщение 111, Уровень 15, Состояние 1, Строка 2' CREATE TRIGGER 'должен быть первым оператором в пакете запроса.

Есть идеи?

Я использую SQL Server 2014.

1 Ответ

0 голосов
/ 25 мая 2018

Мне кажется, я понял это, в основном благодаря этому ответу .

Вот код:

CREATE TRIGGER ddl_trig_createTable   
ON ALL SERVER   
FOR CREATE_TABLE   
AS   
    DECLARE @statement nvarchar(max) = 'CREATE TRIGGER [dbo].[tgrDynamicTableTrigger]
              ON
                [dbo].[DynamicallyCreatedTable]
              AFTER UPDATE
              AS
              BEGIN
                 -- trigger code here
              END'

    DECLARE @databaseName varchar(255)
    DECLARE @AffectedTables varchar(255) 
    SELECT  @AffectedTables = EVENTDATA().value('(/EVENT_INSTANCE/ObjectName)[1]','nvarchar(100)') 
    IF (@AffectedTables IN ('DynamicallyCreatedTable'))
    BEGIN

        SET @databaseName = CAST(eventdata().query('/EVENT_INSTANCE/DatabaseName[1]/text()') as NVarchar(128))

        DECLARE @sql NVARCHAR(MAX) = QUOTENAME(@databaseName) + '.sys.sp_executesql';
        EXEC @sql @statement;

    END
GO  
...