Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Автоматично събиране на данни за промени в схемата на базата данни в MS SQL Server

Въведение

Случвало ли ви се е да се сблъскате със ситуация, когато трябва да направите промени в съхранена процедура или изглед много бързо? Имам, много често, особено на етапа на изпълнение. За съжаление, системата за контрол на версиите не може да помогне в този случай. И все пак, как мога да разбера, че нещо е променено и кога?

Тази статия описва възможно решение за автоматично събиране на данни за промени в схемата на базата данни в MS SQL Server. Както обикновено, ще се радвам да чуя всякакви алтернативни решения.

Решение

  1. Създайте две таблици:първата ще бъде за всяка база данни, втората – за всички бази данни:
    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. Създайте DDL-тригер за база данни, която събира промени в схемата:
    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

Препоръчвам да коригирате филтър и да не правите DDL-тригер за целия сървър. Безполезно е, тъй като ще получите много ненужна информация. В този случай е по-добре да създадете тригер за всяка база данни.
Въпреки това, ще трябва да изключите този тригер по време на сложни операции, например репликация. Но по-късно ще можете да го включите отново.

  1. Ще трябва да съберете информация в една таблица. Например, можете да го направите със задача в SQL Server Agent веднъж седмично.
  2. Възможно е да съберете всичко в една таблица по друг начин, който предпочитате.

Освен това препоръчвам да изтриете стари данни.

Резултат

В тази статия анализирах пример за внедряване на автоматично събиране на данни за промени в схемите на бази данни в MS SQL Server. Позволява ни да разберем какво и кога е променено и, ако е необходимо, да ги върнем. Като цяло, това решение може да бъде полезно на етапа на внедряване, където има много грешки и когато имаме различни версии на бази данни, копия за анализиране. Ако искате да разберете причината за промените, можете да го направите, като извлечете хронология на ревизиите.

Прочетете също:

Автоматично събиране на данни за изпълнени задачи в 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. Разгръщане на LocalDB на клиентски компютър

  2. Актуализиране на таблица с помощта на JOIN в SQL Server?

  3. 3 начина да получите стъпките за работа на работа за агент на SQL Server (T-SQL)

  4. Какво представлява двоен в sql сървър?

  5. DEGREES() Примери в SQL Server