Comment créer déclencheur DDL pour toutes les bases de SQL Server 2005 par exemple
-
09-09-2019 - |
Question
Je vais créer un déclencheur DDL à toutes les bases de données en instance SQL Server. Je voudrais le faire en une seule fois au lieu de plusieurs pistes pour chaque base de données.
Voici les deux instructions T-SQL je dois exécuter:
-- 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
Ma question est: comment puis-je créer programmaticaly déclencheur DDL en une seule fois
La solution
Pourquoi avez-vous besoin d'une course? c'est la seule façon de le faire.
Msg 111, Level 15, State 1, Line 2
'CREATE TRIGGER' must be the first statement in a query batch.
exécuter la sortie générée par celle-ci:
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
EDIT pour déterminer les bases de données pour générer des scripts pour effectuer les opérations suivantes:
-
exécuter cette requête:
sélectionnez database_id, le nom de sys.databases
-
trouver toutes les bases de données que vous souhaitez exécuter les scripts pour
-
modifier mon script ci-dessus en deux endroits (avant la boucle et à fond en boucle) de sorte que tous les database_id que vous voulez sont dans la section de code suivant:
OÙ database_id IN (AAA, BBB, CCC, DDD, ....)
Autres conseils
Vous pouvez utiliser sp_MSforeachdb.
Quelque chose comme ceci
sp_MSforeachdb
'
CREATE TABLE ?.dbo.ChangeAttempt
etc. etc. etc.
'
sp_MSforeachdb
'
CREATE TRIGGER ?.dbo.db_trg_ObjectChanges
etc. etc. etc.
'
Je n'ai pas testé, en théorie je pense que cela fonctionne bien. Vous voulez vous assurer que vous excluez les bases de données du système bien.