sql >> データベース >  >> RDS >> Sqlserver

MSSQLServerでのデータベーススキーマ変更の自動データ収集

    はじめに

    ストアドプロシージャまたはビューを非常に迅速に変更する必要がある状況に直面したことがありますか?私は、特に実装段階で、非常に頻繁に行っています。残念ながら、この場合、バージョン管理システムは役に立ちません。それでも、何かがいつ変更されたかをどうやって理解できますか?

    この記事では、MSSQLServerでのデータベーススキーマの変更に関する自動データ収集の可能な解決策について説明します。いつものように、私は代替の解決策を聞いてうれしいです。

    ソリューション

    1. 2つのテーブルを作成します。1つ目はデータベースごと、2つ目はすべてのデータベース用です。
      USE [DATABASE_NAME]
      GO
      
      SET ANSI_NULLS ON
      GO
      
      SET QUOTED_IDENTIFIER ON
      GO
      
      CREATE TABLE [srv].[ddl_log](
          [DDL_Log_GUID] [uniqueidentifier] NOT NULL,
          [PostTime] [datetime] NOT NULL,
          [DB_Login] [nvarchar](255) NULL,
          [DB_User] [nvarchar](255) NULL,
          [Event] [nvarchar](255) NULL,
          [TSQL] [nvarchar](max) NULL,
       CONSTRAINT [PK_ddl_log] PRIMARY KEY CLUSTERED 
      (
          [DDL_Log_GUID] ASC
      )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
      ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
      
      GO
      
      ALTER TABLE [srv].[ddl_log] ADD  CONSTRAINT [DF_ddl_log_DDL_Log_GUID]  DEFAULT (newid()) FOR [DDL_Log_GUID]
      GO
      
      USE [DATABASE_NAME]
      GO
      
      SET ANSI_NULLS ON
      GO
      
      SET QUOTED_IDENTIFIER ON
      GO
      
      CREATE TABLE [srv].[ddl_log_all](
          [DDL_Log_GUID] [uniqueidentifier] NOT NULL,
          [Server_Name] [nvarchar](255) NOT NULL,
          [DB_Name] [nvarchar](255) NOT NULL,
          [PostTime] [datetime] NOT NULL,
          [DB_Login] [nvarchar](255) NULL,
          [DB_User] [nvarchar](255) NULL,
          [Event] [nvarchar](255) NULL,
          [TSQL] [nvarchar](max) NULL,
          [InsertUTCDate] [datetime] NOT NULL,
       CONSTRAINT [PK_ddl_log_all] PRIMARY KEY CLUSTERED 
      (
          [DDL_Log_GUID] ASC
      )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
      ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
      
      GO
      
      ALTER TABLE [srv].[ddl_log_all] ADD  CONSTRAINT [DF_ddl_log_all_DDL_Log_GUID]  DEFAULT (newid()) FOR [DDL_Log_GUID]
      GO
      
      ALTER TABLE [srv].[ddl_log_all] ADD  CONSTRAINT [DF_ddl_log_all_InsertUTCDate]  DEFAULT (getutcdate()) FOR [InsertUTCDate]
      GO
    2. スキームの変更を収集するデータベースのDDLトリガーを作成します。
      USE [DATABASE_NAME]
      GO
      
      SET ANSI_NULLS ON
      GO
      
      SET QUOTED_IDENTIFIER ON
      GO
      
      CREATE TRIGGER [SchemaLog] 
      ON DATABASE --ALL SERVER 
      FOR DDL_DATABASE_LEVEL_EVENTS 
      AS
          SET NOCOUNT ON;
          SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
          DECLARE @data XML
          begin try
          if(CURRENT_USER<>'NT AUTHORITY\NETWORK SERVICE' and SYSTEM_USER<>'NT AUTHORITY\NETWORK SERVICE')
          begin
              SET @data = EVENTDATA();
              INSERT srv.ddl_log(
                          PostTime,
                          DB_Login,
                          DB_User,
                          Event,
                          TSQL
                        ) 
              select 
                          GETUTCDATE(),
                          CONVERT(nvarchar(255), SYSTEM_USER),
                          CONVERT(nvarchar(255), CURRENT_USER), 
                          @data.value('(/EVENT_INSTANCE/EventType)[1]', 'nvarchar(255)'), 
                          @data.value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'nvarchar(max)')
              where       @data.value('(/EVENT_INSTANCE/EventType)[1]', 'nvarchar(255)') not in('UPDATE_STATISTICS', 'ALTER_INDEX')
                      and @data.value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'nvarchar(max)') not like '%Msmerge%'; 
                          --there is no need in tracking changes of replication objects
          end
          end try
          begin catch
          end catch
      
      GO
      
      SET ANSI_NULLS OFF
      GO
      
      SET QUOTED_IDENTIFIER OFF
      GO
      
      ENABLE TRIGGER [SchemaLog] ON DATABASE
      GO

    サーバー全体に対してDDLトリガーを作成するのではなく、フィルターを調整することをお勧めします。不必要な情報がたくさん出てくるのでダメです。この場合、データベースごとにトリガーを作成することをお勧めします。
    ただし、レプリケーションなどの複雑な操作では、このトリガーをオフにする必要があります。ただし、後でもう一度オンにすることができます。

    1. 単一のテーブルに情報を収集する必要があります。たとえば、SQLServerエージェントのタスクを使用して週に1回実行できます。
    2. 好みの方法ですべてを1つのテーブルに集めることができます。

    さらに、古いデータを削除することをお勧めします。

    結果

    この記事では、MSSQLServerのデータベーススキームの変更に関する自動データ収集を実装する例を分析しました。これにより、何がいつ変更されたかを確認し、必要に応じて元に戻すことができます。一般に、このソリューションは、多くの間違いがある実装段階や、分析するデータベースのコピーのバージョンが異なる場合に役立つ可能性があります。変更の理由を知りたい場合は、改訂履歴を取得することで確認できます。

    また読む:

    MSSQLServerで完了したタスクに関する自動データ収集


    1. SQLJOINの種類

    2. LinuxにMicrosoftSQLをインストールする方法

    3. MS SQL ON DELETE CASCADE同じテーブルを指す複数の外部キー?

    4. バイト長に基づいてUTF8文字列を短縮する最良の方法