在DDL触发器中更改数据库语句

时间:2015-04-18 06:22:34

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

我正在尝试通过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

错误:

  

Msg 226,Level 16,State 6,Line 22
  多语句事务中不允许使用ALTER DATABASE语句。   声明已经终止。

我在Windows 2012上的SQL Server 2014上。

2 个答案:

答案 0 :(得分:1)

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

不需要系统级触发器......

答案 1 :(得分:1)

我意识到DDL触发器将在其自己的事务上,并且如果事务已经启动则不允许Alter。因此,为了解决这个问题,我创建了SQL Job。并将Alters放入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'