【问题标题】:How to create DDL trigger to all databases in SQL Server 2005 instance如何为 SQL Server 2005 实例中的所有数据库创建 DDL 触发器
【发布时间】:2009-06-03 17:42:39
【问题描述】:

我将为 SQL Server 实例中的所有数据库创建一个 DDL 触发器。我想一次运行而不是每个数据库运行多次。

以下是我需要执行的两条 T-SQL 语句:

-- Create table

use <dbname>
GO
CREATE TABLE dbo.ChangeAttempt
(EventData xml NOT NULL,
AttemptDate datetime NOT NULL DEFAULT GETDATE(),
DBUser char(50) NOT NULL)
GO

-- Create DDL trigger 

use <dbname>
GO
CREATE TRIGGER db_trg_ObjectChanges
ON DATABASE
FOR ALTER_PROCEDURE, DROP_PROCEDURE,
 ALTER_INDEX, DROP_INDEX,
 ALTER_TABLE, DROP_TABLE, ALTER_TRIGGER, DROP_TRIGGER,
 ALTER_VIEW, DROP_VIEW, ALTER_SCHEMA, DROP_SCHEMA,
 ALTER_ROLE, DROP_ROLE, ALTER_USER, DROP_USER
AS
SET NOCOUNT ON
INSERT dbo.ChangeAttempt
(EventData, DBUser)
VALUES (EVENTDATA(), USER)
GO

我的问题是:如何在一次运行中以编程方式创建 DDL 触发器?

【问题讨论】:

  • 我用如何编辑我的问题...
  • 那么现在有多快?我怎样才能得到正确的答案但没有投票?
  • 它很快。我可以在几个小时内完成所有 SQL Server 的创建。抱歉,我不知道您所说的“赞成票”是什么意思。我该怎么做?

标签: tsql ddl-trigger


【解决方案1】:

为什么你需要一次跑步?这是唯一的方法。

Msg 111, Level 15, State 1, Line 2
'CREATE TRIGGER' must be the first statement in a query batch.

运行由此生成的输出:

DECLARE @DatabaseName varchar(500)
DECLARE @Database_id  int
DECLARE @Query        varchar(8000)
DECLARE @CRLF         char(2)

SET @CRLF=CHAR(13)+CHAR(10)
---MODIFY THIS TO INCLUDE THE DATABASES THAT YOU WANT TO WORk ON
---MODIFY THIS TO INCLUDE THE DATABASES THAT YOU WANT TO WORk ON
select @Database_id=MIN(database_id) from sys.databases where database_id IN (5,7,8,6)

WHILE @Database_id IS NOT NULL
BEGIN
    SELECT @DatabaseName=name from sys.databases where database_id=@Database_id
    SET @Query='-- Create table'+@CRLF+@CRLF
                +'use '+@DatabaseName+@CRLF
                +' GO'+@CRLF
                +' CREATE TABLE dbo.ChangeAttempt'+@CRLF
                +' (EventData xml NOT NULL,'+@CRLF
                +' AttemptDate datetime NOT NULL DEFAULT GETDATE(),'+@CRLF
                +' DBUser char(50) NOT NULL)'+@CRLF
                +'GO'+@CRLF+@CRLF
                +'-- Create DDL trigger '+@CRLF+@CRLF
                +'use '+@DatabaseName+@CRLF
                +'GO'+@CRLF
                +'CREATE TRIGGER db_trg_ObjectChanges'+@CRLF
                +'ON DATABASE'+@CRLF
                +'FOR ALTER_PROCEDURE, DROP_PROCEDURE,'+@CRLF
                +' ALTER_INDEX, DROP_INDEX,'+@CRLF
                +' ALTER_TABLE, DROP_TABLE, ALTER_TRIGGER, DROP_TRIGGER,'+@CRLF
                +' ALTER_VIEW, DROP_VIEW, ALTER_SCHEMA, DROP_SCHEMA,'+@CRLF
                +' ALTER_ROLE, DROP_ROLE, ALTER_USER, DROP_USER'+@CRLF
                +'AS'+@CRLF
                +'SET NOCOUNT ON'+@CRLF
                +'INSERT dbo.ChangeAttempt'+@CRLF
                +'(EventData, DBUser)'+@CRLF
                +'VALUES (EVENTDATA(), USER)'+@CRLF
                +'GO'+@CRLF
    PRINT @Query
    ---MODIFY THIS TO INCLUDE THE DATABASES THAT YOU WANT TO WORk ON
    ---MODIFY THIS TO INCLUDE THE DATABASES THAT YOU WANT TO WORk ON
    select @Database_id=MIN(database_id) from sys.databases WHERE database_id IN (5,7,8,6) AND database_id>@Database_id
END

编辑
确定要为哪些数据库生成脚本,请执行以下操作:

  • 运行这个查询:

    从 sys.databases 中选择 database_id,name

  • 找到您要为其运行脚本的所有数据库

  • 在两个地方更改我上面的脚本(在循环之前和在循环底部),所以您想要的所有 database_id 都在以下代码部分中:

    WHERE database_id IN (AAA,BBB,CCC,DDD,....)

【讨论】:

  • 我忘了说,我想在 SQL Server 2000 中实现这种审计。我可以尝试哪些选项?
  • 当我在一些服务器上尝试它时,输出缺少一些数据库,我可以通过查询 sys.databases。有什么意见为什么?
  • 我明白了。非常感谢您的进一步解释。
【解决方案2】:

您可以使用 sp_MSforeachdb。

类似的东西

sp_MSforeachdb
'
    CREATE TABLE ?.dbo.ChangeAttempt
        etc. etc. etc.
'
sp_MSforeachdb
'
    CREATE TRIGGER ?.dbo.db_trg_ObjectChanges
        etc. etc. etc.
'

我还没有测试过这个,理论上我希望它可以工作。不过,您要确保排除系统数据库。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-18
    • 1970-01-01
    • 1970-01-01
    • 2011-04-05
    • 1970-01-01
    • 2011-11-02
    • 1970-01-01
    相关资源
    最近更新 更多