Introduzione
Ti è mai capitato di affrontare una situazione in cui è necessario apportare modifiche a una stored procedure o a una visualizzazione molto rapidamente? L'ho fatto, molto spesso, soprattutto in fase di attuazione. Sfortunatamente, un sistema di controllo della versione non può aiutare in questo caso. Tuttavia, come posso capire che qualcosa è stato modificato e quando?
Questo articolo descrive una possibile soluzione per la raccolta automatica dei dati sulle modifiche allo schema del database in MS SQL Server. Come al solito, sarò lieto di ascoltare eventuali soluzioni alternative.
Soluzione
- Crea due tabelle:la prima sarà per ogni database, la seconda – per tutti i database:
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
- Crea un trigger DDL per un database che raccoglie le modifiche allo schema:
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
Raccomando di regolare un filtro e di non creare un trigger DDL per l'intero server. È inutile, poiché otterrai molte informazioni inutili. In questo caso, è meglio creare un trigger per ogni database.
Tuttavia, dovrai disattivare questo trigger durante operazioni complicate, ad esempio la replica. Ma in seguito potrai riaccenderlo.
- Dovrai raccogliere informazioni in un'unica tabella. Ad esempio, puoi farlo con un'attività in SQL Server Agent una volta alla settimana.
- È possibile riunire tutto in una tabella in un altro modo che preferisci.
Inoltre, ti consiglio di eliminare i vecchi dati.
Risultato
In questo articolo, ho analizzato un esempio di implementazione di una raccolta dati automatica sulle modifiche agli schemi dei database in MS SQL Server. Ci consente di scoprire cosa e quando è stato modificato e, se necessario, di ripristinarlo. In generale, questa soluzione può essere utile nella fase di implementazione in cui ci sono molti errori e quando abbiamo diverse versioni di copie di database da analizzare. Se desideri scoprire un motivo per le modifiche, puoi farlo recuperando una cronologia delle revisioni.
Leggi anche:
Raccolta automatica dei dati sulle attività completate in MS SQL Server