Julia :
Also, wer hat gestern mein Verfahren geändert?Lesha :
nicht ichMaxim :
nicht ich-
Leute, können wir Git bekommen?Seryozha :
Es ist höchste Zeit!2 Wochen sind vergangen ...
Julia :
Leute?-
Yul, hast du dich nicht verpflichtet?Julia :
verdammt nein (...So fing alles an. Nun, was, jedes Zeichen und jede Zeile begehen?
Oder passiert das alles vielleicht von alleine?) An diesem Punkt kommen sie in den Sinn
DDL-Trigger ,
Zeittabelle und Bild werden hinzugefügt. Gelöst werden wir Versionen darin speichern
SQL Server'a !)

Erstellen Sie zunächst Tabellen, in denen Versionen gespeichert werden
USE master GO
Es ist wichtig, die Einschränkungen des Zeitplans zu berücksichtigen
.- Nach dem Erstellen können Sie weder auf die Haupt- noch auf die Verlaufstabelle DDL- Befehle anwenden. Und Sie können die temporäre Tabelle nicht löschen
- Sie können keine Daten in der Verlaufstabelle ändern
Die zweite Einschränkung passt zu uns, aber was tun mit der ersten?
Der Algorithmus ist wie folgt:
Obwohl die Tabelle noch keine Indizes enthält, füllen Sie sie mit unseren Prozeduren, Funktionen usw., die mit
INIT gekennzeichnet sind.
Dies bedeutet in unserem Fall die Erstplatzierung
DECLARE @query NVARCHAR(MAX), @template NVARCHAR(MAX) = N' USE [db] INSERT INTO MASTER.dbo.VersionControl WITH (TABLOCKX) ( Event, Db, Sch, Object, Sql, Login ) SELECT ''INIT'' AS Event, DB_NAME(), ss.name AS Sch, so.name AS Object, CONCAT(''<query><![CDATA['', sasm.definition, '']]></query>'' ), SUSER_SNAME() AS Login FROM sys.objects AS so JOIN sys.schemas AS ss ON ss.schema_id = so.schema_id JOIN sys.all_sql_modules AS sasm ON sasm.object_id = so.object_id WHERE so.is_ms_shipped = 0 AND NOT EXISTS ( SELECT 1 FROM MASTER.dbo.VersionControl AS vc WHERE vc.Db = ''[db]'' AND vc.Sch = ss.name AND vc.Object = so.name ); '; DECLARE @databases TABLE (rn INT, Name sysname); INSERT @databases (rn, Name) SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS rn, name FROM sys.databases WHERE owner_sid != 0x01; DECLARE @i INT = 1, @max INT = (SELECT MAX(rn) FROM @databases), @error NVARCHAR(128), @db sysname; WHILE @i < @max BEGIN SELECT @query = REPLACE(@template, '[db]', Name), @db = Name FROM @databases WHERE rn = @i; BEGIN TRY EXECUTE sp_executesql @query; SET @i += 1; CONTINUE; END TRY BEGIN CATCH SET @error = CONCAT( 'XML Parsing error. In this case that''s mean one of [', @db, '] object is invalid for convert to XML' ); PRINT @error; SET @i += 1; CONTINUE; END CATCH; END; GO
Weil Änderungen an den Objekten werden mit der
UPDATE-Anweisung vorgenommen , und wir werden die Versionen am häufigsten nach Schlüssel betrachten: die Datenbank, das Schema und den Namen des Objekts, der Index bittet!
IF NOT EXISTS ( SELECT 1 FROM sys.indexes WHERE name = 'IX_VersionControl_upd_key' ) CREATE UNIQUE NONCLUSTERED INDEX IX_VersionControl_upd_key ON MASTER.dbo.VersionControl (Db, Sch, Object) INCLUDE (Sql, Event, Login);
Alles ist bereit, Versionen zu speichern, und hilft uns bei diesem
DDL-TriggerWichtig! Weil Tabellen für Versionen befinden sich in der
Master- Datenbank. Nach dem Erstellen eines Triggers kann jeder, der keine Rechte an dieser Datenbank hat, keine Objekte ändern, erstellen oder löschen
IF EXISTS ( SELECT 1 FROM sys.server_triggers WHERE name = 'tr_VersionControl' ) DROP TRIGGER tr_VersionControl ON ALL SERVER GO CREATE TRIGGER tr_VersionControl ON ALL SERVER
Zur Vereinfachung der Verwendung dieses Systems wird das folgende Verfahren vorgeschlagen.
Es ist einfach zu bedienen. Das Präfix
sp_ hilft uns beim Zugriff auf die Prozedur, ohne die Datenbank und das Schema anzugeben. Parameter werden intuitiv gefüllt. Sie können nur die Datenbank angeben und es werden nur Objekte angezeigt, die nur für die gesamte Zeit zugeordnet sind. Sie können jedoch auch das Schema, das Objekt selbst und natürlich den Zeitraum verwenden, für den Änderungen vorgenommen wurden.
CREATE PROCEDURE dbo.sp_Vc @db sysname = '%', @sch sysname = '%', @obj sysname = '%', @from DATETIME2(0) = NULL, @to DATETIME2(0) = NULL AS BEGIN SET NOCOUNT ON; IF @from IS NULL AND @to IS NULL BEGIN SELECT * FROM master.dbo.VersionControl WHERE Db LIKE @db AND Sch LIKE @sch AND Object LIKE @obj ORDER BY StartDate DESC END ELSE BEGIN SELECT * FROM master.dbo.VersionControl FOR SYSTEM_TIME BETWEEN @from AND @to WHERE Db LIKE @db AND Sch LIKE @sch AND Object LIKE @obj ORDER BY StartDate DESC END END GO
Nachfolgend finden Sie Beispiele für die Verwendung des Verfahrens
Sie können dieses Mikroframework aus meinem
Repository installieren. Wenn Ihre Version von SQL Server jünger als 2016 ist,
sind Sie
hier . Übrigens verwenden wir diese Version jetzt, aber sie ist nicht so cool.
Abschließend
Ich habe es nie geschafft, die Schlussfolgerung zu besiegen
& _gt; und
& _lt; anstelle der Zeichen
> und
< aus der Tabelle
master.dbo.VersionControl im Feld
SQL . Wenn Sie dabei helfen können oder Ideen haben, warte ich auf eine
Pull-Anfrage .
Vielen Dank für Ihre Zeit, setzen Sie Sterne, Herzen und Pfeile.