Giới thiệu
Bạn đã bao giờ phải đối mặt với tình huống khi bạn cần thực hiện các thay đổi trong một thủ tục được lưu trữ hoặc một dạng xem rất nhanh chóng chưa? Tôi có, rất thường xuyên, đặc biệt là ở giai đoạn thực hiện. Thật không may, một hệ thống kiểm soát phiên bản không thể giúp đỡ trong trường hợp này. Tuy nhiên, làm thế nào tôi có thể hiểu rằng một cái gì đó đã được sửa đổi và khi nào?
Bài viết này mô tả một giải pháp khả thi để thu thập dữ liệu tự động về các thay đổi lược đồ cơ sở dữ liệu trong MS SQL Server. Như thường lệ, tôi sẽ rất vui khi biết bất kỳ giải pháp thay thế nào.
Giải pháp
- Tạo hai bảng:bảng đầu tiên sẽ dành cho mỗi cơ sở dữ liệu, bảng thứ hai - cho tất cả các cơ sở dữ liệu:
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
- Tạo trình kích hoạt DDL cho cơ sở dữ liệu thu thập các thay đổi lược đồ:
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
Tôi khuyên bạn nên điều chỉnh một bộ lọc và không tạo DDL-trigger cho toàn bộ máy chủ. Nó là vô ích, vì bạn sẽ nhận được rất nhiều thông tin không cần thiết. Trong trường hợp này, tốt hơn là tạo một trình kích hoạt cho từng cơ sở dữ liệu.
Tuy nhiên, bạn sẽ phải tắt trình kích hoạt này trong các hoạt động phức tạp, ví dụ:sao chép. Nhưng sau đó, bạn sẽ có thể bật lại.
- Bạn sẽ cần thu thập thông tin trong một bảng. Ví dụ:bạn có thể làm điều đó với một tác vụ trong SQL Server Agent một lần một tuần.
- Có thể tập hợp mọi thứ vào một bảng theo cách khác mà bạn thích.
Ngoài ra, tôi khuyên bạn nên xóa dữ liệu cũ.
Kết quả
Trong bài viết này, tôi đã phân tích một ví dụ về việc triển khai thu thập dữ liệu tự động về những thay đổi của lược đồ cơ sở dữ liệu trong MS SQL Server. Nó cho phép chúng tôi tìm hiểu những gì và khi nào đã được sửa đổi, và nếu cần, để hoàn nguyên chúng. Nói chung, giải pháp này có thể hữu ích ở giai đoạn thực hiện có rất nhiều lỗi và khi chúng tôi có các phiên bản khác nhau của các bản sao cơ sở dữ liệu cần phân tích. Nếu bạn muốn tìm ra lý do cho các thay đổi, bạn có thể làm điều đó bằng cách truy xuất lịch sử sửa đổi.
Cũng đọc:
Thu thập dữ liệu tự động về các công việc đã hoàn thành trong MS SQL Server