Julia :
Jadi, siapa yang mengubah prosedur saya kemarin?Lesha :
bukan akuMaxim :
bukan aku-
Bisakah kita mendapatkan Git?Seryozha :
sudah saatnya!2 minggu telah berlalu ...
Julia :
teman-teman?-
Yul, bukankah kamu berkomitmen?Julia :
sial tidak (...Begitulah semuanya dimulai. Nah, apa, setiap karakter dan setiap baris komit?
Atau mungkin semua ini akan terjadi dengan sendirinya?) Pada titik ini, mereka mulai datang ke pikiran
Pemicu DDL ,
tabel temporal dan gambar ditambahkan. Diselesaikan, kami akan menyimpan versi di dalamnya
SQL Server'a !)

Pertama, buat tabel di mana versi akan disimpan
USE master GO
Penting untuk mengingat keterbatasan dari
tabel temporal.- Setelah membuatnya, Anda tidak bisa menerapkan perintah DDL ke tabel utama atau historis. Dan Anda tidak dapat menghapus tabel Temporal
- Anda tidak dapat mengubah data dalam tabel historis
Pembatasan kedua cocok untuk kita, tetapi apa yang harus dilakukan dengan yang pertama?
Algoritma adalah sebagai berikut:
Meskipun belum ada indeks di atas meja, isilah dengan prosedur, fungsi, dll, bertanda
INIT , yang dalam kasus kami berarti penempatan awal
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
Karena perubahan pada objek akan terjadi dengan
pernyataan UPDATE , dan kita akan paling sering melihat versi dengan kunci: database, skema dan nama objek, indeks memohon!
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);
Semuanya siap untuk mulai menyimpan versi dan akan membantu kami dengan
Pemicu DDL ini
Penting! Karena tabel untuk versi ada di database
master , setelah membuat pemicu, semua orang yang tidak memiliki hak untuk database ini tidak dapat memodifikasi, membuat, atau menghapus objek
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
Dan untuk kenyamanan menggunakan sistem ini, prosedur di bawah ini diusulkan.
Ini mudah digunakan. Awalan
sp_ akan membantu kami mengakses prosedur tanpa menentukan basis data dan skema. Parameter diisi secara intuitif. Anda hanya dapat menentukan basis data dan kami akan melihat objek yang hanya dikaitkan dengannya sepanjang waktu, tetapi Anda juga dapat menggunakan skema, objek itu sendiri, dan tentu saja rentang waktu perubahan yang dibuat.
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
Di bawah ini adalah contoh penggunaan prosedur
Anda dapat menginstal struktur mikro ini dari
repositori saya, dan jika versi SQL Sever Anda lebih muda dari 2016, maka di
sinilah Anda. Omong-omong, kami menggunakan versi ini sekarang, tetapi tidak terlalu keren.
Kesimpulannya
Saya tidak pernah berhasil mengalahkan kesimpulan
& _gt; dan
& _lt; alih-alih tanda
> dan
< dari tabel
master.dbo.VersionControl oleh bidang
Sql . Jika Anda dapat membantu dengan ini atau memiliki ide, saya sedang menunggu
Permintaan Tarik .
Terima kasih atas waktu Anda, letakkan bintang, hati, dan panah atas.