Úvod
Setkali jste se někdy se situací, kdy potřebujete velmi rychle provést změny v uložené proceduře nebo pohledu? Mám, velmi často, zejména ve fázi realizace. Systém správy verzí v tomto případě bohužel nepomůže. Přesto, jak mohu pochopit, že bylo něco změněno a kdy?
Tento článek popisuje možné řešení pro automatický sběr dat o změnách databázového schématu na MS SQL Server. Jako obvykle rád uslyším jakékoli alternativní řešení.
Řešení
- Vytvořte dvě tabulky:první bude pro každou databázi, druhá – pro všechny databáze:
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
- Vytvořte spouštěč DDL pro databázi, která shromažďuje změny schématu:
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
Doporučuji upravit filtr a nedělat DDL-trigger pro celý server. Je to zbytečné, protože získáte spoustu zbytečných informací. V tomto případě je lepší vytvořit spouštěč pro každou databázi.
Tento spouštěč však budete muset vypnout při složitých operacích, například při replikaci. Později jej však budete moci znovu zapnout.
- Budete muset shromáždit informace v jedné tabulce. Můžete to například provést pomocí úlohy v SQL Server Agent jednou týdně.
- Je možné shromáždit vše v jedné tabulce jiným způsobem, který preferujete.
Dále doporučuji smazat stará data.
Výsledek
V tomto článku jsem rozebral příklad implementace automatického sběru dat o změnách databázových schémat na MS SQL Server. Umožňuje nám zjistit, co a kdy bylo změněno, a v případě potřeby je vrátit zpět. Obecně může být toto řešení užitečné ve fázi implementace, kde je mnoho chyb a kdy máme různé verze kopií databází k analýze. Chcete-li zjistit důvod změn, můžete to udělat načtením historie revizí.
Přečtěte si také:
Automatický sběr dat o dokončených úkolech na MS SQL Server