{"id":287414,"date":"2018-08-16T14:08:44","date_gmt":"2018-08-16T10:08:44","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=287414"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2018-08-16T10:08:44","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=287414","title":{"rendered":"\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u0432\u0435\u0440\u0441\u0438\u0439 \u0432\u043d\u0443\u0442\u0440\u0438 SQL Server&#8217;a"},"content":{"rendered":"\n<div data-io-article-url=\"https:\/\/habr.com\/post\/419919\/\" class=\"post__text post__text-html js-mediator-article\"><b>\u042e\u043b\u044f<\/b>: <i>\u0422\u0430\u043a, \u043a\u0442\u043e \u0432\u0447\u0435\u0440\u0430 \u043c\u0435\u043d\u044f\u043b \u043c\u043e\u044e \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0443? <\/i><br \/>  <b>\u041b\u0451\u0448\u0430<\/b>: <i>\u043d\u0435 \u044f<\/i><br \/>  <b>\u041c\u0430\u043a\u0441\u0438\u043c<\/b>: <i>\u043d\u0435 \u044f<\/i><br \/>   \u2014 <i>\u0420\u0435\u0431\u044f\u0442, \u043c\u043e\u0436\u0435\u0442 Git \u0437\u0430\u0432\u0435\u0434\u0451\u043c ?<\/i><br \/>  <b>\u0421\u0435\u0440\u0451\u0436\u0430<\/b>: <i>\u0434\u0430\u0432\u043d\u043e \u043f\u043e\u0440\u0430!<\/i><br \/>  \u043f\u0440\u043e\u0448\u043b\u043e 2 \u043d\u0435\u0434\u0435\u043b\u0438\u2026<\/p>\n<p>  <b>\u042e\u043b\u044f<\/b>: <i>\u0440\u0435\u0431\u044f\u044f\u044f\u0442?<\/i><br \/>   \u2014 <i>\u042e\u043b\u044c, \u0430 \u0442\u044b \u043d\u0435 \u043a\u043e\u043c\u043c\u0438\u0442\u0438\u043b\u0430?<\/i><br \/>  <b>\u042e\u043b\u044f<\/b>: <s><i>damn<\/i><\/s> <i>\u043d\u0435\u0442(\u2026<\/i><\/p>\n<p>  \u0412\u043e\u0442 \u0442\u0430\u043a \u0432\u0441\u0451 \u0438 \u043d\u0430\u0447\u0430\u043b\u043e\u0441\u044c. \u041d\u0443 \u0430 \u0447\u0442\u043e, \u043a\u0430\u0436\u0434\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b \u0438 \u043a\u0430\u0436\u0434\u0443\u044e \u0441\u0442\u0440\u043e\u0447\u043a\u0443 \u043a\u043e\u043c\u043c\u0438\u0442\u0438\u0442\u044c? <\/p>\n<p>  \u0410 \u043c\u043e\u0436\u0435\u0442 \u0432\u0441\u0451 \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u0441\u0430\u043c\u043e?) \u041d\u0430 \u044d\u0442\u043e\u043c \u043c\u043e\u043c\u0435\u043d\u0442\u0435 \u0432 \u0433\u043e\u043b\u043e\u0432\u0443 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u044c <br \/>  <a href=\"https:\/\/docs.microsoft.com\/ru-ru\/sql\/relational-databases\/triggers\/ddl-triggers?view=sql-server-2017\">DDL-\u0442\u0440\u0438\u0433\u0433\u0435\u0440\u044b<\/a>, <a href=\"https:\/\/docs.microsoft.com\/ru-ru\/sql\/relational-databases\/tables\/temporal-tables?view=sql-server-2017\">Temporal table<\/a> \u0438 \u043a\u0430\u0440\u0442\u0438\u043d\u0430 \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f. \u0420\u0435\u0448\u0435\u043d\u043e, \u0431\u0443\u0434\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432\u0435\u0440\u0441\u0438\u0438 \u0432\u043d\u0443\u0442\u0440\u0438 <br \/>  <a href=\"https:\/\/www.microsoft.com\/ru-ru\/sql-server\/sql-server-2017\">SQL Server&#8217;a<\/a> !)<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/dn\/fe\/f3\/dnfef3bqd49qysawcaxvuuiasdi.jpeg\"><\/p>\n<p>  <a name=\"habracut\"><\/a><br \/>  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0431\u0443\u0434\u0443\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0432\u0435\u0440\u0441\u0438\u0438<\/p>\n<pre><code class=\"sql\">USE master GO   -- \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u0441\u0442\u043e\u0440\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443 IF NOT EXISTS ( \tSELECT 1  \tFROM sys.objects \tWHERE name = 'VersionControlHistory' \t\tAND type = 'U' ) \tCREATE TABLE dbo.VersionControlHistory( \t\tId INT NOT NULL, \t\tEvent sysname NOT NULL, \t\tDb sysname NOT NULL, \t\tSch sysname NOT NULL, \t\tObject sysname NOT NULL, \t\tSql XML NOT NULL, \t\tLogin sysname NOT NULL, \t\tStartDate DATETIME2(0) NOT NULL, \t\tEndDate DATETIME2(0) NOT NULL \t)  ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO   -- \u0410 \u0437\u0430\u0442\u0435\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0436\u0443\u0440\u043d\u0430\u043b\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 IF NOT EXISTS ( \tSELECT 1  \tFROM sys.objects \tWHERE name = 'VersionControl' \t\tAND type = 'U' ) \tCREATE TABLE dbo.VersionControl( \t\tId INT IDENTITY(1,1) NOT NULL CONSTRAINT PK_VersionControl  \t\t\tPRIMARY KEY NONCLUSTERED, \t\tEvent sysname NOT NULL, \t\tDb sysname NOT NULL, \t\tSch sysname NOT NULL, \t\tObject sysname NOT NULL, \t\tSql XML NOT NULL, \t\tLogin sysname NOT NULL, \t\tStartDate DATETIME2(0) GENERATED ALWAYS AS ROW START NOT NULL, \t\tEndDate DATETIME2(0) GENERATED ALWAYS AS ROW END NOT NULL, \t\tPERIOD FOR SYSTEM_TIME (StartDate, EndDate) \t) WITH (  \t\tSYSTEM_VERSIONING = ON ( \t\t\tHISTORY_TABLE = dbo.VersionControlHistory \t\t) \t) GO <\/code><\/pre>\n<p>  \u0412\u0430\u0436\u043d\u043e \u043f\u043e\u043c\u043d\u0438\u0442\u044c \u043e\u0431 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f\u0445 \u0434\u043b\u044f <a href=\"https:\/\/docs.microsoft.com\/ru-ru\/sql\/relational-databases\/tables\/temporal-tables?view=sql-server-2017\">Temporal table<\/a> <\/p>\n<ol>\n<li> \u041f\u043e\u0441\u043b\u0435 \u0438\u0445 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0432\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c <a href=\"https:\/\/msdn.microsoft.com\/ru-ru\/library\/ff848799(v=sql.120).aspx\">DDL<\/a> \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043d\u0438 \u043a \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439, \u043d\u0438 \u043a \u0438\u0441\u0442\u043e\u0440\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u043c. \u0418 \u043d\u0435\u043b\u044c\u0437\u044f \u0443\u0434\u0430\u043b\u044f\u0442\u044c <a href=\"https:\/\/docs.microsoft.com\/ru-ru\/sql\/relational-databases\/tables\/temporal-tables?view=sql-server-2017\">Temporal table<\/a><\/li>\n<li> \u041d\u0435\u043b\u044c\u0437\u044f \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0438\u0441\u0442\u043e\u0440\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435<\/li>\n<\/ol>\n<p>  \u0412\u0442\u043e\u0440\u043e\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043d\u0430\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442, \u0430 \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0441 \u043f\u0435\u0440\u0432\u044b\u043c? <\/p>\n<p>  \u0410\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0442\u0430\u043a\u043e\u0439:<\/p>\n<pre><code class=\"sql\">-- \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0432\u0435\u0440\u0441\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 ALTER TABLE dbo.VersionControl SET ( SYSTEM_VERSIONING = OFF );  \/*     \u0447\u0442\u043e-\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u043c *\/  --\u0418 \u0441\u043d\u043e\u0432\u0430 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439: ALTER TABLE dbo.VersionControl SET (  \tSYSTEM_VERSIONING = ON (  \t\tHISTORY_TABLE = dbo.VersionControlHistory,  \t\tDATA_CONSISTENCY_CHECK = OFF \t); <\/code><\/pre>\n<p>  \u041f\u043e\u043a\u0430 \u043d\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0435\u0449\u0435 \u043d\u0435\u0442 \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432, \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u0435\u0451 \u043d\u0430\u0448\u0438\u043c\u0438 \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0430\u043c\u0438, \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438 \u0438 \u043f\u0440. \u0441 \u043f\u043e\u043c\u0435\u0442\u043a\u043e\u0439 <b>INIT<\/b>, \u0447\u0442\u043e \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0437\u043d\u0430\u0447\u0430\u0442\u044c \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u043e\u0435 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435<\/p>\n<pre><code class=\"sql\">DECLARE @query NVARCHAR(MAX), \t@template NVARCHAR(MAX) = N' USE [db]  INSERT INTO MASTER.dbo.VersionControl WITH (TABLOCKX) ( \tEvent, Db, Sch, Object, Sql, Login )  \tSELECT ''INIT'' AS Event, \t\tDB_NAME(), \t\tss.name AS Sch, \t\tso.name AS Object, \t\tCONCAT(''&lt;query&gt;&lt;![CDATA['', sasm.definition, '']]&gt;&lt;\/query&gt;'' ), \t\tSUSER_SNAME() AS Login \tFROM sys.objects AS so \t\tJOIN sys.schemas AS ss ON ss.schema_id = so.schema_id \t\tJOIN sys.all_sql_modules AS sasm ON sasm.object_id = so.object_id \tWHERE so.is_ms_shipped = 0 \t\tAND NOT EXISTS ( \t\t\tSELECT 1 \t\t\tFROM MASTER.dbo.VersionControl AS vc \t\t\tWHERE vc.Db = ''[db]'' \t\t\t\tAND vc.Sch = ss.name \t\t\t\tAND vc.Object = so.name \t\t\t); '; DECLARE @databases TABLE (rn INT, Name sysname); \tINSERT @databases (rn, Name) \t\tSELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS rn, name \t\tFROM sys.databases \t\tWHERE owner_sid != 0x01;  DECLARE @i INT = 1,  \t@max INT = (SELECT MAX(rn) FROM @databases), \t@error NVARCHAR(128), \t@db sysname;  WHILE @i &lt; @max BEGIN  \tSELECT @query = REPLACE(@template, '[db]', Name), \t\t@db = Name \tFROM @databases \tWHERE rn = @i;  \tBEGIN TRY \t\tEXECUTE sp_executesql @query; \t\tSET @i += 1; \t\tCONTINUE; \tEND TRY \tBEGIN CATCH \t\tSET @error = CONCAT( \t\t\t'XML Parsing error. In this case that''s mean one of [',  \t\t\t@db, '] object is invalid for convert to XML' \t\t); \t\tPRINT @error; \t\tSET @i += 1; \t\tCONTINUE; \tEND CATCH;  END; GO <\/code><\/pre>\n<p>  \u0422.\u043a. \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0435\u0439 <a href=\"https:\/\/docs.microsoft.com\/ru-ru\/sql\/t-sql\/queries\/update-transact-sql?view=sql-server-2017\">UPDATE<\/a>, \u0430 \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0435\u0440\u0441\u0438\u0438 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0447\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u043f\u043e \u043a\u043b\u044e\u0447\u0443: \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, \u0441\u0445\u0435\u043c\u0430 \u0438 \u0438\u043c\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u043d\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u043d\u0434\u0435\u043a\u0441!<\/p>\n<pre><code class=\"sql\">IF NOT EXISTS ( \tSELECT 1 \tFROM sys.indexes \tWHERE name = 'IX_VersionControl_upd_key' ) \tCREATE UNIQUE NONCLUSTERED INDEX IX_VersionControl_upd_key  \t\tON MASTER.dbo.VersionControl (Db, Sch, Object) \t\tINCLUDE (Sql, Event, Login); <\/code><\/pre>\n<p>  \u0412\u0441\u0451 \u0433\u043e\u0442\u043e\u0432\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0447\u0430\u0442\u044c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432\u0435\u0440\u0441\u0438\u0438 \u0438 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u043c \u0432 \u044d\u0442\u043e\u043c <a href=\"https:\/\/docs.microsoft.com\/ru-ru\/sql\/relational-databases\/triggers\/ddl-triggers?view=sql-server-2017\">DDL-\u0422\u0440\u0438\u0433\u0433\u0435\u0440<\/a><\/p>\n<p>  <b>\u0412\u0430\u0436\u043d\u043e!<\/b> \u0422.\u043a. \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0434\u043b\u044f \u0432\u0435\u0440\u0441\u0438\u0439 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 <b>master<\/b>, \u043f\u043e\u0441\u043b\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430, \u0432\u0441\u0435 \u0443 \u043a\u043e\u0433\u043e \u043d\u0435\u0442 \u043f\u0440\u0430\u0432 \u043d\u0430 \u044d\u0442\u0443 \u0431\u0430\u0437\u0443, \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c, \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438 \u0443\u0434\u0430\u043b\u044f\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043d\u0435 \u0441\u043c\u043e\u0433\u0443\u0442<\/p>\n<pre><code class=\"sql\">IF EXISTS ( \tSELECT 1 \tFROM sys.server_triggers \tWHERE name = 'tr_VersionControl' ) \tDROP TRIGGER tr_VersionControl ON ALL SERVER GO CREATE TRIGGER tr_VersionControl ON ALL SERVER --WITH ENCRYPTION -- \u043f\u043e \u0436\u0435\u043b\u0430\u043d\u0438\u044e \/*\t\u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043e\u0442\u043b\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c\u044b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \t\u043f\u043e\u043b\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0441\u043e\u0431\u044b\u0442\u0438\u0439:  \t\thttps:\/\/docs.microsoft.com\/ru-ru\/sql\/relational-databases\/triggers\/ddl-events?view=sql-server-2017 *\/ FOR \tCREATE_TABLE, ALTER_TABLE, DROP_TABLE, \tCREATE_VIEW, ALTER_VIEW, DROP_VIEW, \tCREATE_FUNCTION, ALTER_FUNCTION, DROP_FUNCTION, \tCREATE_PROCEDURE, ALTER_PROCEDURE, DROP_PROCEDURE, \tCREATE_ASSEMBLY, ALTER_ASSEMBLY, DROP_ASSEMBLY, \tCREATE_INDEX, ALTER_INDEX, DROP_INDEX, \tCREATE_TRIGGER, ALTER_TRIGGER, DROP_TRIGGER, \tRENAME AS BEGIN \tSET NOCOUNT ON;  \tUPDATE vs \tSET vs.Event =  ev.EventType, \t\tvs.Sql = CONCAT('&lt;query&gt;&lt;!CDATA', ev.Sql, '&gt;&lt;\/query&gt;' ), \t\tvs.Login = ev.Login \tFROM MASTER.dbo.VersionControl AS vs \t\tJOIN ( \t\t\tSELECT *  \t\t\tFROM ( VALUES ( \t\t\t\tEVENTDATA().value( \t\t'(\/EVENT_INSTANCE\/EventType)[1]', 'NVARCHAR(128)' \t\t\t\t), \t\t\t\tEVENTDATA().value( \t\t'(\/EVENT_INSTANCE\/SchemaName)[1]', 'NVARCHAR(128)' \t\t\t\t), \t\t\t\tEVENTDATA().value( \t\t'(\/EVENT_INSTANCE\/ObjectName)[1]', 'NVARCHAR(128)' \t\t\t\t), \t\t\t\tEVENTDATA().value( \t\t'(\/EVENT_INSTANCE\/TSQLCommand\/CommandText)[1]', 'NVARCHAR(MAX)' \t\t\t\t), \t\t\t\tEVENTDATA().value( \t\t'(\/EVENT_INSTANCE\/LoginName)[1]', 'NVARCHAR(128)' \t\t\t\t) \t\t\t)) AS Event (EventType, Sch, Object, Sql, Login )  \t\t) ev ON vs.Db = DB_NAME() \t\t\tAND vs.Sch = ev.Sch \t\t\tAND vs.Object = ev.Object \t;  END GO <\/code><\/pre>\n<p>  \u0410 \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0430 \u043d\u0438\u0436\u0435.<\/p>\n<p>  \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0435\u0439 \u043f\u0440\u043e\u0441\u0442\u043e. \u041f\u0440\u0435\u0444\u0438\u043a\u0441 <b>sp_<\/b> \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u043c \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0435 \u0431\u0435\u0437 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0441\u0445\u0435\u043c\u044b. \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u043e. \u041c\u043e\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u043d\u0435\u0439 \u0437\u0430 \u0432\u0441\u0451 \u0432\u0440\u0435\u043c\u044f, \u0430 \u043c\u043e\u0436\u043d\u043e \u0438 \u0441\u0445\u0435\u043c\u0443, \u0438 \u0441\u0430\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d, \u0437\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u044b\u043b\u0438 \u0432\u043d\u0435\u0441\u0435\u043d\u044b \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f.<\/p>\n<pre><code class=\"sql\"> CREATE PROCEDURE dbo.sp_Vc  \t@db sysname = '%',  \t@sch sysname = '%', \t@obj sysname = '%', \t@from DATETIME2(0) = NULL, \t@to DATETIME2(0) = NULL  AS BEGIN \tSET NOCOUNT ON; \t \tIF @from IS NULL AND @to IS NULL BEGIN \t\tSELECT * \t\tFROM master.dbo.VersionControl \t\tWHERE Db LIKE @db \t\t\tAND Sch LIKE @sch \t\t\tAND Object LIKE @obj \t\tORDER BY StartDate DESC \tEND \tELSE BEGIN\t \t\tSELECT * \t\tFROM master.dbo.VersionControl  \t\t\tFOR SYSTEM_TIME BETWEEN @from AND @to \t\tWHERE Db LIKE @db \t\t\tAND Sch LIKE @sch \t\t\tAND Object LIKE @obj \t\tORDER BY StartDate DESC \tEND  END GO <\/code><\/pre>\n<p>  \u041d\u0438\u0436\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u044b<\/p>\n<pre><code class=\"sql\">-- \u0432\u044b\u0432\u043e\u0434 \u0432\u0441\u0435\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0437\u0430 \u0432\u0441\u0451 \u0432\u0440\u0435\u043c\u044f sp_Vc;  \/* \u0432\u044b\u0432\u043e\u0434 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043f\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445  \t\u0437\u0430 \u0432\u0441\u0451 \u0432\u0440\u0435\u043c\u044f *\/ sp_Vc 'dwh';  \/* \u0432\u044b\u0432\u043e\u0434 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043f\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0441\u0445\u0435\u043c\u0435 \t\u0437\u0430 \u0432\u0441\u0451 \u0432\u0440\u0435\u043c\u044f *\/ sp_Vc 'dwh', 'dbo';  \/* \u0432\u044b\u0432\u043e\u0434 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043f\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u0441\u0445\u0435\u043c\u0435 \t\u0438 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u0443 \u0437\u0430 \u0432\u0441\u0451 \u0432\u0440\u0435\u043c\u044f *\/ sp_Vc 'dwh', 'dbo', 'MyObject';  \/* \u0432\u044b\u0432\u043e\u0434 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043f\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u0441\u0445\u0435\u043c\u0435, \t\u0438 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u0443 \u0437\u0430 \u043f\u0435\u0440\u0438\u043e\u0434 \u0441 1-\u0433\u043e \u043f\u043e 9-\u0435 \u043c\u0430\u044f *\/ sp_Vc 'dwh', 'dbo', 'MyObject', '20180501 00:00:00', '20180509 00:00:00'; <\/code><\/pre>\n<p>  \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043c\u0438\u043a\u0440\u043e\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441 \u043c\u043e\u0435\u0433\u043e <a href=\"https:\/\/github.com\/lestatkim\/opensql\/blob\/master\/VersionControl\/VersionControl_mssql2016.sql\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f<\/a>, \u0430 \u0435\u0441\u043b\u0438 \u0432\u0430\u0448\u0430 \u0432\u0435\u0440\u0441\u0438\u044f SQL Sever&#8217;a \u043c\u043b\u0430\u0434\u0448\u0435 2016-\u0439, \u0442\u043e\u0433\u0434\u0430 \u0432\u0430\u043c <a href=\"https:\/\/github.com\/lestatkim\/opensql\/tree\/master\/VersionControl\/VersionControl\">\u0441\u044e\u0434\u0430<\/a>. \u041a\u0441\u0442\u0430\u0442\u0438, \u044d\u0442\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0435\u0439 \u043c\u044b \u0441\u0435\u0439\u0447\u0430\u0441 \u0438 \u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f, \u043d\u043e \u043e\u043d\u0430 \u043d\u0435 \u0442\u0430\u043a\u0430\u044f \u043a\u043b\u0430\u0441\u0441\u043d\u0430\u044f.<\/p>\n<h3>\u0412 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h3>\n<p>  \u041c\u043d\u0435 \u0442\u0430\u043a \u0438 \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0431\u0435\u0434\u0438\u0442\u044c \u0432\u044b\u0432\u043e\u0434 <b>&amp;_gt;<\/b> \u0438 <b>&amp;_lt;<\/b> \u0432\u043c\u0435\u0441\u0442\u043e \u0437\u043d\u0430\u043a\u043e\u0432 <b>&gt;<\/b> \u0438 <b>&lt;<\/b> \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b <b>master.dbo.VersionControl<\/b> \u043f\u043e \u043f\u043e\u043b\u044e <b>Sql<\/b>. \u0415\u0441\u043b\u0438 \u0442\u044b \u043c\u043e\u0436\u0435\u0448\u044c \u043f\u043e\u043c\u043e\u0447\u044c \u0441 \u044d\u0442\u0438\u043c \u0438\u043b\u0438 \u0443 \u0442\u0435\u0431\u044f \u0435\u0441\u0442\u044c \u0438\u0434\u0435\u0438, \u0436\u0434\u0443 <a href=\"https:\/\/ru.stackoverflow.com\/questions\/134183\/%D0%A7%D1%82%D0%BE-%D1%82%D0%B0%D0%BA%D0%BE%D0%B5-pull-request\">Pull Request&#8217;a <\/a>.<\/p>\n<p>  \u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0447\u0442\u043e \u0443\u0434\u0435\u043b\u0438\u043b\u0438 \u0432\u0440\u0435\u043c\u044f, \u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u0437\u0432\u0451\u0437\u0434\u043e\u0447\u043a\u0438, \u0441\u0435\u0440\u0434\u0435\u0447\u043a\u0438 \u0438 \u0441\u0442\u0440\u0435\u043b\u043e\u0447\u043a\u0438 \u0432\u0432\u0435\u0440\u0445.<\/p><\/div>\n<p>        <script class=\"js-mediator-script\">!function(e){function t(t,n){if(!(n in e)){for(var r,a=e.document,i=a.scripts,o=i.length;o--;)if(-1!==i[o].src.indexOf(t)){r=i[o];break}if(!r){r=a.createElement(\"script\"),r.type=\"text\/javascript\",r.async=!0,r.defer=!0,r.src=t,r.charset=\"UTF-8\";var d=function(){var e=a.getElementsByTagName(\"script\")[0];e.parentNode.insertBefore(r,e)};\"[object Opera]\"==e.opera?a.addEventListener?a.addEventListener(\"DOMContentLoaded\",d,!1):e.attachEvent(\"onload\",d):d()}}}t(\"\/\/mediator.mail.ru\/script\/2820404\/\",\"_mediator\")}(window);<\/script>     <br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/post\/419919\/\"> https:\/\/habr.com\/post\/419919\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div data-io-article-url=\"https:\/\/habr.com\/post\/419919\/\" class=\"post__text post__text-html js-mediator-article\"><b>\u042e\u043b\u044f<\/b>: <i>\u0422\u0430\u043a, \u043a\u0442\u043e \u0432\u0447\u0435\u0440\u0430 \u043c\u0435\u043d\u044f\u043b \u043c\u043e\u044e \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0443? <\/i><br \/>  <b>\u041b\u0451\u0448\u0430<\/b>: <i>\u043d\u0435 \u044f<\/i><br \/>  <b>\u041c\u0430\u043a\u0441\u0438\u043c<\/b>: <i>\u043d\u0435 \u044f<\/i><br \/>   \u2014 <i>\u0420\u0435\u0431\u044f\u0442, \u043c\u043e\u0436\u0435\u0442 Git \u0437\u0430\u0432\u0435\u0434\u0451\u043c ?<\/i><br \/>  <b>\u0421\u0435\u0440\u0451\u0436\u0430<\/b>: <i>\u0434\u0430\u0432\u043d\u043e \u043f\u043e\u0440\u0430!<\/i><br \/>  \u043f\u0440\u043e\u0448\u043b\u043e 2 \u043d\u0435\u0434\u0435\u043b\u0438\u2026<\/p>\n<p>  <b>\u042e\u043b\u044f<\/b>: <i>\u0440\u0435\u0431\u044f\u044f\u044f\u0442?<\/i><br \/>   \u2014 <i>\u042e\u043b\u044c, \u0430 \u0442\u044b \u043d\u0435 \u043a\u043e\u043c\u043c\u0438\u0442\u0438\u043b\u0430?<\/i><br \/>  <b>\u042e\u043b\u044f<\/b>: <s><i>damn<\/i><\/s> <i>\u043d\u0435\u0442(\u2026<\/i><\/p>\n<p>  \u0412\u043e\u0442 \u0442\u0430\u043a \u0432\u0441\u0451 \u0438 \u043d\u0430\u0447\u0430\u043b\u043e\u0441\u044c. \u041d\u0443 \u0430 \u0447\u0442\u043e, \u043a\u0430\u0436\u0434\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b \u0438 \u043a\u0430\u0436\u0434\u0443\u044e \u0441\u0442\u0440\u043e\u0447\u043a\u0443 \u043a\u043e\u043c\u043c\u0438\u0442\u0438\u0442\u044c? <\/p>\n<p>  \u0410 \u043c\u043e\u0436\u0435\u0442 \u0432\u0441\u0451 \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u0441\u0430\u043c\u043e?) \u041d\u0430 \u044d\u0442\u043e\u043c \u043c\u043e\u043c\u0435\u043d\u0442\u0435 \u0432 \u0433\u043e\u043b\u043e\u0432\u0443 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u044c <br \/>  <a href=\"https:\/\/docs.microsoft.com\/ru-ru\/sql\/relational-databases\/triggers\/ddl-triggers?view=sql-server-2017\">DDL-\u0442\u0440\u0438\u0433\u0433\u0435\u0440\u044b<\/a>, <a href=\"https:\/\/docs.microsoft.com\/ru-ru\/sql\/relational-databases\/tables\/temporal-tables?view=sql-server-2017\">Temporal table<\/a> \u0438 \u043a\u0430\u0440\u0442\u0438\u043d\u0430 \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f. \u0420\u0435\u0448\u0435\u043d\u043e, \u0431\u0443\u0434\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432\u0435\u0440\u0441\u0438\u0438 \u0432\u043d\u0443\u0442\u0440\u0438 <br \/>  <a href=\"https:\/\/www.microsoft.com\/ru-ru\/sql-server\/sql-server-2017\">SQL Server&#8217;a<\/a> !)<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/dn\/fe\/f3\/dnfef3bqd49qysawcaxvuuiasdi.jpeg\"><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-287414","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/287414","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=287414"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/287414\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=287414"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=287414"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=287414"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}