SQL Server 2005 インスタンスのすべてのデータベースに対する DDL トリガーを作成する方法
-
09-09-2019 - |
質問
SQL Server インスタンス内のすべてのデータベースに対する DDL トリガーを作成します。データベースごとに何度も実行するのではなく、1 回の実行で実行したいと考えています。
以下は、実行する必要がある 2 つの 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
私の質問は次のとおりです。プログラムで 1 回の実行で DDL トリガーを作成するにはどうすればよいですか?
解決
なぜ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を選択します
スクリプトを実行するすべてのデータベースを見つけます
上記のスクリプトを変更します 2か所で (ループの前とループの最後)したがって、必要なすべてのdatabase_idは次のコードセクションにあります。
WHERE データベース ID IN (AAA、BBB、CCC、DDD、....)
他のヒント
あなたはsp_MSforeachdbを使用することができます。
このような何か。
sp_MSforeachdb
'
CREATE TABLE ?.dbo.ChangeAttempt
etc. etc. etc.
'
sp_MSforeachdb
'
CREATE TRIGGER ?.dbo.db_trg_ObjectChanges
etc. etc. etc.
'
私は理論的には、私はそれが動作することを期待したい、これをテストしていません。あなたはあなたがが、システムのデータベースを除外することを確認したいと思います。
所属していません StackOverflow