SQL Server 2005 인스턴스의 모든 데이터베이스에 DDL 트리거를 만드는 방법

StackOverflow https://stackoverflow.com/questions/946118

  •  09-09-2019
  •  | 
  •  

문제

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 트리거를 만들 수 있습니까?

도움이 되었습니까?

해결책

한 번의 달리기가 필요한 이유는 무엇입니까? 이것이 유일한 방법입니다.

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, 이름을 선택하십시오

  • 스크립트를 실행하려는 모든 데이터베이스를 찾으십시오.

  • 위의 스크립트를 변경하십시오 두 곳에서 (루프 전 및 루프의 하단에) 따라서 원하는 모든 Database_id는 다음 코드 섹션에 있습니다.

    여기서 database_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.
'

나는 이것을 테스트하지 않았다. 이론적으로는 그것이 효과가있을 것으로 기대한다. 그래도 시스템 데이터베이스를 제외해야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top