[sql] SQL Server 테이블의 변경 사항을 확인 하시겠습니까?

트리거를 사용하거나 데이터베이스 구조를 수정하지 않고 테이블 변경 사항을 SQL Server 데이터베이스에서 어떻게 모니터링 할 수 있습니까? 내가 선호하는 프로그래밍 환경은 .NET 및 C #입니다.

모든 SQL Server 2000 SP4 이상 을 지원하고 싶습니다 . 내 응용 프로그램은 다른 회사 제품의 볼트 온 데이터 시각화입니다. 고객 기반은 수천 명이므로 모든 설치시 타사 공급 업체의 테이블을 수정해야하는 요구 사항을 적용하고 싶지 않습니다.

에 의해 “테이블로 변경” , 테이블 데이터에 대한 I 평균 변경 테이블 구조를 변경하지.

궁극적으로 변경 사항을 주기적으로 확인하지 않고 응용 프로그램에서 이벤트를 트리거하기 위해 변경 사항을 원합니다.


내 요구 사항 (트리거 또는 스키마 수정 없음, SQL Server 2000 및 2005)을 고려한 가장 좋은 방법 BINARY_CHECKSUMT-SQL 에서 함수 를 사용하는 것 같습니다 . 구현하려는 방법은 다음과 같습니다.

X 초마다 다음 쿼리를 실행합니다.

SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*))
FROM sample_table
WITH (NOLOCK);

그리고 저장된 값과 비교하십시오. 값이 변경된 경우 쿼리를 사용하여 행 단위로 테이블을 진행하십시오.

SELECT row_id, BINARY_CHECKSUM(*)
FROM sample_table
WITH (NOLOCK);

그리고 반환 된 체크섬과 저장된 값을 비교합니다.



답변

CHECKSUM 명령을 살펴보십시오.

SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM sample_table WITH (NOLOCK);

테이블 내용이 변경되지 않은 한 실행될 때마다 동일한 숫자를 반환합니다. 자세한 내용은 내 게시물을 참조하십시오.

체크섬

다음은 테이블이 변경 될 때 캐시 종속성을 다시 작성하는 데 사용한 방법입니다.
ASP.NET 1.1 데이터베이스 캐시 종속성 (트리거없이)


답변

불행히도 CHECKSUM이 변경 사항을 감지하기 위해 항상 제대로 작동하는 것은 아닙니다 .

기본 체크섬 일 뿐이며 CRC (Cyclic Redundancy Check) 계산은 없습니다.

따라서 모든 변경 사항을 감지하는 데 사용할 수 없습니다. 예를 들어 대칭 변경으로 인해 동일한 CHECKSUM이 발생합니다!

예 : 솔루션 CHECKSUM_AGG(BINARY_CHECKSUM(*))은 내용이 다른 3 개의 테이블 모두에 대해 항상 0을 제공합니다.


SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM
(
  SELECT 1 as numA, 1 as numB
  UNION ALL
  SELECT 1 as numA, 1 as numB
)  q
-- delivers 0!

SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM ( SELECT 1 as numA, 2 as numB UNION ALL SELECT 1 as numA, 2 as numB ) q -- delivers 0!

SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM ( SELECT 0 as numA, 0 as numB UNION ALL SELECT 0 as numA, 0 as numB ) q -- delivers 0!


답변

왜 트리거를 사용하고 싶지 않습니까? 올바르게 사용하면 좋은 것입니다. 참조 무결성을 강화하기위한 방법으로 사용하는 경우, 좋은 상태에서 나쁜 상태로 전환 될 때입니다. 그러나 모니터링에 사용하면 실제로 금기 사항으로 간주되지 않습니다.


답변

변경 사항을 얼마나 자주 점검해야하며 데이터베이스의 테이블 크기 (행 크기)는 얼마나됩니까? CHECKSUM_AGG(BINARY_CHECKSUM(*))John이 제안한 방법 을 사용 하면 지정된 테이블의 모든 행을 스캔합니다. NOLOCK힌트는 도움이되지만 큰 데이터베이스에, 당신은 여전히 모든 행을 타격 있습니다. 또한 모든 행에 대한 체크섬을 저장해야 하나의 행이 변경되었음을 알 수 있습니다.

다른 각도에서 이것을 고려한 적이 있습니까? 트리거를 추가하기 위해 스키마를 수정하지 않으려는 경우 (이는 데이터베이스가 아님) 데이터베이스를 만드는 응용 프로그램 공급 업체와의 작업을 고려하고 있습니까?

액세서리 앱에 데이터가 변경되었음을 알리는 메커니즘을 제공하는 API를 구현할 수 있습니다. 어떤 테이블과 어떤 행이 수정되었는지 나열하는 알림 테이블에 쓰는 것만 큼 간단 할 수 있습니다. 이는 트리거 또는 애플리케이션 코드를 통해 구현 될 수 있습니다. 당신의 측면에서, 중요하지 않을 것입니다, 당신의 유일한 관심사는 정기적으로 알림 테이블을 스캔하는 것입니다. 데이터베이스의 성능 적중은 모든 행에서 변경 사항을 검색하는 것보다 훨씬 적습니다.

어려운 부분은 응용 프로그램 공급 업체가이 기능을 구현하도록 설득하는 것입니다. 이는 트리거를 통해 SQL을 통해 완전히 처리 할 수 ​​있으므로 트리거를 작성 및 테스트 한 후 코드를 응용 프로그램 공급 업체에 가져 와서 많은 작업을 수행 할 수 있습니다. 공급 업체가 트리거를 지원하게하면 트리거를 추가하면 공급 업체가 제공 한 트리거가 실수로 교체되는 상황이 방지됩니다.


답변

불행히도 SQL2000에는 이것을 할 수있는 확실한 방법이 없다고 생각합니다. 요구 사항을 SQL Server 2005 이상으로 좁 히면 사업을 시작한 것입니다. 의 SQLDependency클래스를 사용할 수 있습니다 System.Data.SqlClient. SQL Server의 쿼리 알림 (ADO.NET)을 참조하십시오 .


답변

주어진 간격으로 실행되는 DTS 작업 (또는 Windows 서비스에서 시작한 작업)이 있어야합니다. 실행될 때마다 시스템 INFORMATION_SCHEMA 테이블 을 사용하여 지정된 테이블에 대한 정보를 얻고이 데이터를 데이터 저장소에 기록합니다. 테이블 구조와 관련하여 리턴 된 데이터와 이전에 리턴 된 데이터를 비교하십시오. 다른 경우 구조가 변경되었음을 알 수 있습니다.

ABC 테이블의 모든 열에 대한 정보를 반환하는 쿼리 예제 (이상적으로는 여기서처럼 * select **를 사용하는 대신 원하는 INFORMATION_SCHEMA 테이블의 열만 나열) :

select * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'ABC'

“테이블 변경”을 정확히 정의하는 방법에 따라 다른 열과 INFORMATION_SCHEMA보기를 모니터링합니다.


답변

여기서 와일드 추측 : 타사의 테이블을 수정하지 않으려면 뷰를 생성 한 다음 해당 뷰에 트리거를 적용 할 수 있습니까?