Einführung
Sind Sie schon einmal in eine Situation geraten, in der Sie sehr schnell Änderungen an einer gespeicherten Prozedur oder einer Ansicht vornehmen mussten? Das habe ich sehr oft, besonders in der Umsetzungsphase. Ein Versionskontrollsystem kann hier leider nicht helfen. Wie kann ich trotzdem verstehen, dass etwas geändert wurde und wann?
Dieser Artikel beschreibt eine mögliche Lösung für die automatische Datenerfassung über Datenbankschemaänderungen in MS SQL Server. Wie üblich freue ich mich über alternative Lösungen.
Lösung
- Erstellen Sie zwei Tabellen:die erste für jede Datenbank, die zweite für alle Datenbanken:
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
- Erstellen Sie einen DDL-Trigger für eine Datenbank, die Schemaänderungen sammelt:
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
Ich empfehle, einen Filter einzustellen und keinen DDL-Trigger für den gesamten Server zu machen. Es ist nutzlos, da Sie viele unnötige Informationen erhalten. In diesem Fall ist es besser, für jede Datenbank einen Trigger zu erstellen.
Bei komplizierten Vorgängen, z. B. Replikation, müssen Sie diesen Trigger jedoch deaktivieren. Aber später können Sie es wieder einschalten.
- Sie müssen Informationen in einer einzigen Tabelle sammeln. Beispielsweise können Sie dies einmal pro Woche mit einer Aufgabe im SQL Server Agent tun.
- Es ist möglich, alles auf eine andere Art und Weise, die Sie bevorzugen, in einer Tabelle zu sammeln.
Außerdem empfehle ich, alte Daten zu löschen.
Ergebnis
In diesem Artikel habe ich ein Beispiel für die Implementierung einer automatischen Datenerfassung über Änderungen von Datenbankschemata in MS SQL Server analysiert. Es ermöglicht uns, herauszufinden, was und wann geändert wurde, und sie bei Bedarf rückgängig zu machen. Im Allgemeinen kann diese Lösung in der Implementierungsphase hilfreich sein, wenn es viele Fehler gibt und wenn wir verschiedene Versionen von Datenbankkopien haben, die analysiert werden müssen. Wenn Sie den Grund für Änderungen herausfinden möchten, können Sie dies tun, indem Sie eine Änderungshistorie abrufen.
Lesen Sie auch:
Automatische Datenerfassung über abgeschlossene Aufgaben in MS SQL Server