【问题标题】:SQL Server 2014 Create DDL trigger on Create Table that creates a trigger for the tableSQL Server 2014 在为表创建触发器的 Create Table 上创建 DDL 触发器
【发布时间】:2018-05-23 20:51:28
【问题描述】:

我正在使用创建数据库和表的第三方工具。我想在其中一个正在创建的表上触发。我想我会尝试创建一个在新数据库中创建表时触发的服务器 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< ---

但是,在创建表时会产生以下错误:

Msg 111, Level 15, State 1, Line 2 'CREATE TRIGGER' 必须是第一个 查询批处理中的语句。

有什么想法吗?

我使用的是 SQL Server 2014。

【问题讨论】:

  • 我想问你为什么首先需要那个触发器。触发器可能很有用,但它们通常不是工作的正确工具。这对我来说似乎是一个 xy 问题。 xyproblem.info

标签: sql-server ddl


【解决方案1】:

我相信我已经弄明白了,这主要归功于answer。

代码如下:

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  

【讨论】:

    猜你喜欢
    • 2019-03-08
    • 2014-02-02
    • 2011-03-22
    • 1970-01-01
    • 1970-01-01
    • 2014-05-04
    • 1970-01-01
    • 1970-01-01
    • 2020-01-07
    相关资源
    最近更新 更多