Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Thu thập dữ liệu tự động của các thay đổi lược đồ cơ sở dữ liệu trong MS SQL Server

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

  1. 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
  2. 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.

  1. 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.
  2. 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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tách chuỗi trong máy chủ sql

  2. Chèn dữ liệu trong SQL Server 2017

  3. SQL Server 2012 gói dịch vụ 1 và bản cập nhật tích lũy 1

  4. Các giá trị được phân tách bằng dấu phẩy bằng Truy vấn SQL

  5. Danh sách các loại dữ liệu trong SQL Server 2017