【问题标题】:Alter Database Statement in DDL Trigger在 DDL 触发器中更改数据库语句
【发布时间】:2015-04-18 20:46:34
【问题描述】:

我正在尝试通过 DDL 触发器来更改数据库,该触发器将在创建时触发。但是我收到以下错误。

CREATE TRIGGER ddl_trig_database 
ON ALL SERVER 
FOR CREATE_DATABASE 
AS 
    declare @dbname as nvarchar(100)
    declare @sql as nvarchar(max)

    select @dbname = 
        CAST(eventdata().query(
        '/EVENT_INSTANCE/DatabaseName[1]/text()'
        ) as NVarchar(128))
    select @sql = N'SET IMPLICIT_TRANSACTIONS OFF
    ALTER DATABASE ' + @dbname+ N' SET COMPATIBILITY_LEVEL = 110
    SET IMPLICIT_TRANSACTIONS ON'
    exec  (@sql)
GO
create database test

错误:

消息 226,第 16 级,状态 6,第 22 行
多语句事务中不允许使用 ALTER DATABASE 语句。 声明已终止。

我在 Windows 2012 上使用 SQL Server 2014。

【问题讨论】:

    标签: sql sql-server sql-server-2014


    【解决方案1】:

    如果您想为每个创建的新数据库设置特定的兼容性级别 - 只需在 model 数据库中设置该兼容性级别,这是所有正在创建的新数据库的“模板”...

    无需为此设置系统级触发器 ....

    【讨论】:

    • 我希望针对某些数据库设置一个条件,并且不希望它全部存在。
    • @ShijuSamuel:但如果您有系统范围的触发器 - 这些设置将应用于所有新数据库......
    【解决方案2】:

    我意识到 DDL 触发器将在它自己的事务上,如果事务已经启动,则不允许更改。因此,为了解决这个问题,我创建了 SQL 作业。并将Alter放入Job并修改Trigger以调用msdb..start_sql_job。

    --Trigger
    CREATE TRIGGER ddl_trig_database 
    ON ALL SERVER 
    FOR CREATE_DATABASE 
    AS 
        exec msdb..sp_start_job 'Initialize Database'   
    GO
    
    --Job
    declare @dbname as nvarchar(100)
    declare @sql as nvarchar(max)
    select top 1 @dbname =  name from sys.databases 
        where name like 'gtp%' and create_date >= getdate()  - .08
        order by create_date desc
    IF @dbname is not null
    begin
        select @sql = N'ALTER DATABASE ' + @dbname+ N' SET COMPATIBILITY_LEVEL = 110'
        exec sp_executesql @sql
        print 'Altered database'
    end
    print 'completed'
    

    【讨论】:

      猜你喜欢
      • 2011-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-15
      • 2016-04-03
      • 1970-01-01
      相关资源
      最近更新 更多