sql >> データベース >  >> RDS >> Sqlserver

SQL Serverの変更データキャプチャ(CDC)テーブルから履歴または監査ビューを作成する方法-SQLServerチュートリアル

    シナリオ:

    SQL Server DBAまたは開発者として作業しており、SQL Serverデータベースの1つで変更データキャプチャを有効にしました。CDCを有効にした後、AUDITまたはHISTビューを作成するため、変更されたレコードを取得できます。

    解決策:

    以下のスクリプトは、データベースでCDCが有効になっているテーブルごとにビューを作成します。スクリプトを実行する前に監査スキーマを使用しました。監査スキーマを作成する必要があります。または、履歴スキーマでビューを作成する場合は、次のように変更します。監査から履歴までの以下のコードのスキーマ。
    各ビューは、列の下に戻ります
    • Commit_Time、
    • Colon_Name、
    • Old_Value、
    • New_Value、
    • ModifiedBy




    IF OBJECT_ID(N'tempdb..##CDC_TableList') IS NOT NULL
    BEGIN
        DROP TABLE ##CDC_TableList
    END
    
    SELECT T.name AS TableName,
           C.name AS ColumnName,
           'CASE WHEN (sys.Fn_cdc_is_bit_set (sys.Fn_cdc_get_column_ordinal (''dbo_'
           + T.name + ''',''' + C.name+
           + '''),__$update_mask) = 1) THEN Cast('
           + C.Name
           + ' AS SQL_VARIANT) ELSE NULL END AS '
           + C.name  AS CaseStm INTO ##CDC_TableList
     FROM   sys.tables T
           INNER JOIN sys.columns c
                   ON T.OBJECT_ID = c.OBJECT_ID
    WHERE  is_tracked_by_cdc = 1
           AND c.is_identity = 0
           AND C.name NOT IN ( 'CreatedBy', 'CreatedDate', 'ModifiedBy', 'ModifiedDate' )
           AND T.TYPE='U'
           AND T.is_ms_shipped<>1
          
          -- Select * from sys.tables
    
    DECLARE @TableName NVARCHAR(200)
    DECLARE cdc_cursor CURSOR FOR 
    SELECT DISTINCT TableName FROM ##CDC_TableList
    OPEN cdc_cursor 
    FETCH NEXT FROM cdc_cursor INTO @TableName
    
    WHILE @@FETCH_STATUS = 0 
    BEGIN
    
    DECLARE @ColumnList  NVARCHAR(MAX)
    DECLARE @CaseStmList NVARCHAR(MAX)
    DECLARE @SQL_Stm  NVARCHAR(MAX)
    DECLARE @SQL_Stm_DropView  NVARCHAR(MAX)
    PRINT @TableName
    
     SELECT @ColumnList = STUFF(o.COLUMNNAME, 1, 1, '')
     FROM ##CDC_TableList t CROSS APPLY  (SELECT ',' + ColumnName+CHAR(10) AS [text()]
                FROM  ##CDC_TableList c
                WHERE    c.TableName = t.TableName
                FOR XML PATH('')) o (COLUMNNAME)
     WHERE t.TableName=@TableName
     PRINT @ColumnList
     
     SELECT @CaseStmList = STUFF(o.COLUMNNAME, 1, 1, '')
     FROM ##CDC_TableList t CROSS APPLY  (SELECT ',' + CaseStm+CHAR(10) AS [text()]
                FROM  ##CDC_TableList c
                WHERE    c.TableName = t.TableName
                FOR XML PATH('')) o (COLUMNNAME)
     WHERE t.TableName=@TableName
     --PRINT @CaseStmList
    
    
    --If using Other Schema than AUDIT THEN change to that.
    SET @SQL_Stm=' CREATE VIEW AUDIT.vw_'+@TableName+' AS
    
    SELECT sys.Fn_cdc_map_lsn_to_time(up_b.__$start_lsn) AS Commit_Time, up_b.Column_Name, up_b.Old_Value, up_a.New_Value,up_a.ModifiedBy
    FROM
        ( SELECT __$start_lsn, column_name, old_value,ModifiedBy
       FROM (SELECT __$start_lsn,'+@CaseStmList+',ModifiedBy FROM cdc.fn_cdc_get_all_changes_dbo_'+@TableName+'( sys.fn_cdc_get_min_lsn(''dbo_'+@TableName+'''), sys.fn_cdc_map_time_to_lsn(''largest less than or equal'',GETDATE()), N''all update old'')
     WHERE __$operation = 3
      ) AS BeforeUpdate
      UNPIVOT (old_value FOR column_name IN ('+@ColumnList+') ) AS unp) AS up_b INNER JOIN
      (SELECT __$start_lsn, column_name, new_value,ModifiedBy
       FROM (SELECT __$start_lsn,'+@CaseStmList+',ModifiedBy FROM cdc.fn_cdc_get_all_changes_dbo_'+@TableName+'(sys.fn_cdc_get_min_lsn(''dbo_'+@TableName+'''), sys.fn_cdc_map_time_to_lsn(''largest less than or equal'',GETDATE()), N''all'')
        WHERE __$operation = 4
       ) AS AfterUpdate
       UNPIVOT (new_value FOR column_name IN ('+@ColumnList+') ) AS unp ) AS up_a
    ON up_b.__$start_lsn = up_a.__$start_lsn AND up_b.column_name = up_a.column_name'
    --Drop View if already exists
    SET @SQL_Stm_DropView= 'IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS
             WHERE TABLE_NAME = ''vw_'+@TableName+''')
       DROP VIEW AUDIT.vw_'+@TableName
       PRINT @SQL_Stm_DropView
    
    EXEC (@SQL_Stm_DropView)
    EXEC ( @SQL_Stm)
    FETCH NEXT FROM cdc_cursor INTO @TableName
    END 
    
    CLOSE cdc_cursor 
    DEALLOCATE cdc_cursor

    1. setFetchSize()をいつ何を指定する必要がありますか?

    2. PostgreSQLベースのアプリケーションパフォーマンス:レイテンシと隠れた遅延

    3. SQLServerで変更データキャプチャを使用してインクリメンタルロードを実装する

    4. SQLServerでのDateTimeのYYYY-MM-DD形式への変換