TODD 의 사과농장

테이블 내 레코드 변화를 기록하는 방법 (MSSQL CDC) 본문

Development/MS-SQL

테이블 내 레코드 변화를 기록하는 방법 (MSSQL CDC)

TODD 2013. 7. 24. 08:42

MS-SQL 2008 버젼부터 CDC(Change Data Capture) 기능이 생겼습니다. 


테이블 내 변경되는 데이터를 기록하는 것으로 (행 전체 또는 일부 컬럼) INSERT, DELETE 는 물론 UPDATE 전/후 모두를 기록할 수 있습니다. 이런 작업은 SQL 트랜잭션 로그에서 정보를 읽어오는 방식이라 OLTP 에는 큰 영향을 미치지 않습니다. 


데이터의 변경을 추적하기 위해서 아주 유용한 서비스이지만 한 가지 제약이 있습니다.

Enterprise 버젼에서만 사용이 가능하다는 점인데요. 

Enterprise 를 사용할 수 없는 환경에서 CDC 와 유사한 운영이 가능한 프로시져를 소개합니다.


아래 프로시져는 tbl_ChangeData 에 현재 상태의 레코드 정보를 기록하는 쿼리입니다.

INSERT/UPDATE/DELETE 가 발생하기 전 이 쿼리를 수행함으로서 현재 상태를 간단히 기록할 수 있습니다.



파라미터

@Table VARCHAR(30)

@Key INT

@CustomerNo INT

@KeyField VARCHAR(30) = 'No_'


쿼리

SET NOCOUNT ON

DECLARE @SQL NVARCHAR(MAX)

DECLARE @A NVARCHAR(100)

DECLARE @B NVARCHAR(50)

DECLARE @C NVARCHAR(50)


SET @SQL = 'INSERT INTO tbl_ChangeData (CustomerNo,TableName, KeyData, Created, LogText) SELECT ' + STR(@CustomerNo) + ',' + @Table + ''',' + STR(@Key) + ',GETDATE(), '


DECLARE C_DATA CURSOR FOR

SELECT 

COLUMN_NAME, DATA_TYPE, COLLATION_NAME 

FROM 

INFORMATION_SCHEMA.COLUMNS 

WHERE 

TABLE_NAME = @Table

OPEN C_DATA FETCH NEXT FROM C_DATA INTO @A, @B, @C

WHILE (@@fetch_status = 0)

BEGIN


SET @SQL = @SQL + 

CASE

WHEN @B = 'int' OR @B = 'tinyint' OR @B = 'bit' OR @B = 'money' OR @B = 'text' THEN 'CAST(ISNULL([' + @A + '],'''') AS VARCHAR)'

WHEN @B = 'datetime' OR @B = 'smalldatetime' THEN 'CONVERT(VARCHAR, ISNULL([' + @A + '],''''),120)'

WHEN @B = 'varchar' OR @B = 'char' OR @B = 'nvarchar' THEN 'ISNULL([' + @A + '],'''')'

ELSE ' '''',, '

END


IF (@C = 'Korean_Wansung_CS_AS')

SET @SQL = @SQL + ' COLLATE Korean_Wansung_CI_AS'

SET @SQL = @SQL + ' + ''┃'' + '

FETCH NEXT FROM C_DATA INTO @A, @B, @C

END

CLOSE C_DATA

DEALLOCATE C_DATA


SET @SQL = SUBSTRING(@SQL, 0, LEN(@SQL)) + ' FROM ' + @Table + ' (NOLOCK) WHERE ' + @KeyField + ' = ' + STR(@Key)

--print @sql

EXEC sp_executesql @SQL


Comments