2011-02-23 4 views
2

비즈니스 규칙 내에서 행이 변경되는 것으로 지정되는 시점을 추적해야합니다. 테이블에는 비즈니스 목적에 따라 관련이없는 것으로 지정된 여러 열 (예 : 날짜 입력 필드, 타임 스탬프, 검토 된 비트 필드 또는 수신 된 비트 필드)이 포함되어 있습니다. 테이블에 많은 열이 있고 관련 필드가 변경되었는지 확인한 다음 감사 테이블에 항목을 기록하는 우아한 방법을 찾으려고합니다. 행의 PK 값을 입력하면 PK를 편집 할 수 없습니다. 어떤 컬럼이 실제로 변경되었는지는 알 필요가 없습니다 (길 아래에서 좋을지라도).특정 열의 변경 사항을 제외하고 행을 변경 한 것으로 식별하십시오.

내가 저장 프로 시저를 통해 달성 할 수 있어요,하지만 업데이트를 다음 구문을 사용 못생긴 SP (또는 문이 게시물에 대한 상당히 단축) :

INSERT INTO [TblSourceDataChange] (pkValue) 
    SELECT d.pkValue 
    FROM deleted d INNER JOIN inserted i ON d.pkValue=i.pkValue 
    WHERE ( i.[F440] <> d.[F440] 
      OR i.[F445] <> d.[F445] 
      OR i.[F450] <> d.[F450]) 

내가 찾을려고을 무시 필드와 저장 프로 시저를 지정할 수있는 일반적인 방법은 테이블에 관련 필드를 추가해도 작동합니다. 비 관련 필드는 자주 변경되지 않지만 관련 필드는 좀 더 동적 인 경향이 있습니다.

+0

관련성 높은 이전 질문에 대한 새로운 답변을 추가했습니다. http://stackoverflow.com/questions/1254787/sql-server-update-trigger-get-only-modified-fields/8020461#8020461 –

답변

1

Change Data Capture을 살펴보십시오. 열을 추적하는

EXEC sys.sp_cdc_enable_db

그런 다음 특정 테이블에서 활성화 및 지정할 수 있습니다 :

이 데이터베이스에 CDC 수 있도록 SQL 서버 2008

우선의 새로운 기능입니다

EXEC sys.sp_cdc_enable_table 
    @source_schema = 'dbo', 
    @source_name = 'xxx', 
    @supports_net_changes = 1, 
    @role_name = NULL, 
    @captured_column_list = N'xxx1,xxx2,xxx3' 

그러면 cdc.dbo_xxx이라는 변경 테이블이 생성됩니다. 테이블의 레코드 변경 사항은 해당 테이블에 기록됩니다.

+0

이것은 해결책 일 수 있지만, 실제로 어떤 열이 추적되지 않는지 (가능한 경우) 방법론을 사용하려고합니다. –

+0

바이너리 체크섬 또는 체크섬 분석 (실제로 익숙하지 않고 작동하는 경우) –

+0

변경 내용 추적을 볼 수 있습니다. Change Data Capture Lite와 같습니다. 추적 할 열을 지정할 필요는 없지만 변경 사항에 대한 정보는 거의 얻지 못합니다 (특히 삭제). 참조 : http://msdn.microsoft.com/en-us/library/cc280462.aspx – TGnat

0

트리거를 사용하여 여러 행 삽입을 처리 할 수 ​​있는지 확인하십시오.

1

개체가 있습니다. 사용할 수있는 옵션을 설명하는 데 사용할 수없는 한 단어는 우아합니다. 나는 당신이 원하는 것을 성취하기위한 만족스러운 방법을 아직 찾지 못했습니다. 옵션이 있지만, 모두 조금 불만족 스럽습니다. 언제/왜 옵션을 선택했는지는 언급하지 않은 몇 가지 요인에 따라 다릅니다.

  • 얼마나 자주 필드를 변경해야합니까? 즉, 사용자가 자주 "감사 내역"링크를 클릭합니까? 아니면 항상 앱이 어떻게 동작해야 하는지를 정리할 시간인가?
  • 디스크 공간에 어느 정도의 비용이 듭니까? 나는 경박 한 것은 아니지만, 우리가 산 공간에 대해 청구 한 것에 기초하여 감사를위한 저장 전략이 백만 달러의 문제가 된 곳에서 일했습니다 - SQL 서버를 재구성하는 데 비용이 많이 듭니다. 크기는이었다. 당신은 아마 동일하거나 반대 일 수 있습니다. @TGnat는 CDC를 사용할 수 있습니다 언급 한 바와 같이

변경 데이터는

을 캡처합니다. 이 방법은 변경 추적을 활성화 한 다음 sproc을 호출하여 추적을 시작하기 때문에 유용합니다. CDC는 꽤 효율적인 저장 장치이고 마력이 현명하기 때문에 좋습니다. 개발자는 테이블의 모양을 바꾸고 싶을 때까지 그것을 설정하고 잊어 버립니다. 개발자 정신 나간을 위해 엔티티 추적을 사용 또는 사용하지 않도록 설정하는 스크립트를 생성해야합니다.

특정 열을 포함하지 말고 제외하고 싶습니다.FOR XML PATH 트릭을 사용하여이를 수행 할 수 있습니다. 당신은가 내가 볼 두 번째 옵션은 코드 생성의 일종을 가지고있다

SET @capturedColList = SELECT Substring((
       SELECT ',' + COLUMN_Name 
       FROM INFORMATION_SCHEMA.COLUMNS 
       WHERE TABLE_NAME = '<YOUR_TABLE>' AND 
         COLUMN_NAME NOT IN ('excludedA', 'excludedB') 

       FOR XML PATH('') 
      ) , 2, 8000) 

트리거 케이스/승 .. sys.sp_cdc_enable_table를 호출 할 때 다음 @capturedColList 변수를 사용하여 다음과 같은 쿼리 뭔가를 작성할 수 있습니다. 트리거를 쓰는 외부 하네스 또는 SPROC 일 수 있습니다. 당신의 독이 무엇이든간에, 그것은 자동화되고 일반화 될 필요가 있습니다. 그러나 기본적으로 각 열에 대해 여러 가지 CASE 문을 사용하여 INSERTED 또는 DELETED와 현재를 비교하는 트리거에 대해 DDL을 작성하는 코드를 작성할 것입니다.

스타일 here에 대한 설명이 있습니다.

로그 다, 정렬 그것을 나중에

마지막 옵션은 모든 행 변화를 기록하는 트리거를 사용하는 것입니다. 그런 다음 로그 데이터를 살 l보고 변경이 _ 생한 때를 인식 할 수있는 코드 (SPROCS/UDF)를 작성합니다. 왜이 옵션을 선택하겠습니까? 디스크 공간은 문제가되지 않으며 변경된 내용을 이해할 수 있어야하지만 시스템에이 질문을하는 경우는 드뭅니다.

HTH,

-Eric

+0

정보 주셔서 감사합니다! 내 질문에 대해 혼란스럽게 생각하는 것은 변경 사항을 감사하는 것처럼 보입니다. 디스크 공간이 문제가되지 않습니다. Google 시스템은 세금 신고서를 계산하고 소스 데이터로 식별되는 표를 보유하고 있습니다.이 중 하나라도 변경하면 세금 계산에 영향을 미칩니다. 우리 시스템은 TblSourceDataChange 테이블 (여기에는 나열되지 않은 추가 필드가 있음)을 조사하여 변경된 소스 데이터로 계산을 식별합니다. 계산이 매우 복잡하기 때문에 열 수준을 수행하지 않으며 '아마도'변경된 결과 만 필요합니다. 그 다음 해에는 동일한 테이블 구조를 사용합니다. –

+0

@user <이상한 숫자가있는> - 사용 사례가 위에서 언급 한 것과 다르긴하지만 "나중에 로그 아웃하고 정렬"하는 것이 적절할 것입니다. 하지만, 귀하의 변경 빈도는 (매년?) 명확하지 않습니다. "나중에 정렬"하는 방법에 대해서는 언급하지 않았지만 쿼리를 통해 변경 사항마다 고유 한 행을 생성 할 수 있으므로 절묘하게 그룹 별 절을 효과적으로 수행 할 수 있습니다. 이러한 쿼리 생성을 자동화해야합니다. HTL, -eric – EBarr

0

나는 포스트 SQL Server Update, Get only modified fields에서 답을 발견하고 (이 SQL 트리거에) 내 요구에 맞게 SQL 적응. 는 SQL은 아래에 게시 :을 sysobjects P로부터

DECLARE @idTable INT SELECT @idTable = T.id sysobjects의 T ON P.parent_obj = T.id WHERE P.id = @@ procid

가입 IF EXISTS (SELECT * FROM syscolumns where id = @id 테이블
& POWER (CONVERT (BIGINT, 2), colorder - 1)> 0 및 이름이 없습니다 ('타임 스탬프 ','Reviewed ') ) BEGIN - 여기에 적절한 내용이 있음 END

+0

FYI : COLUMNS_UPDATED() 함수가 열이 변경되었음을 나타내지 만 이는 항상 사실이 아닙니다. 그것은 열이 '만져 졌음'을 의미하지만 잘되었을 수도 있습니다 : UPDATE myTable SET myField = MyField. 다시 말하지만, 아마도 트리거 상단에서 시작하는 것이 좋을 것입니다. 따라서 아무 것도 누르지 않으면 삽입 및 삭제와 일치 할 필요가 없습니다. 추 신 : ColumnsUpdated는 UPDATE()로 각 열을 따로 검사하는 것보다 빠릅니다. – deroby

관련 문제