Skenario:
Anda bekerja sebagai SQL Server DBA atau pengembang, Anda telah mengaktifkan Ubah Pengambilan Data di salah satu Database SQL Server, Setelah mengaktifkan CDC Anda ingin membuat Tampilan AUDIT ATAU HISTsehingga bisa mendapatkan catatan yang diubah.Solusi:
Skrip di bawah ini akan membuat tampilan untuk setiap tabel di mana CDC diaktifkan di database Anda. Saya telah menggunakan Skema Audit, sebelum Anda menjalankan skrip, Anda perlu membuat Skema Audit atau Jika Anda ingin membuat tampilan di Skema Hist, ubah Skema dalam Kode Di Bawah dari Audit Ke Hist.Setiap tampilan akan mengembalikan kita di bawah kolom
- Waktu_Komit,
- Nama_Kolom,
- Nilai_Lama,
- Nilai_Baru,
- Diubah Oleh
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