문제

트리거를 사용하거나 어떤 방식으로든 데이터베이스 구조를 수정하지 않고 SQL Server 데이터베이스에서 테이블 변경 사항을 모니터링하려면 어떻게 해야 합니까?내가 선호하는 프로그래밍 환경은 .그물 그리고 C#.

어떤 지원이든 하고 싶습니다. SQL 서버 2000 SP4 이상.내 애플리케이션은 다른 회사 제품에 대한 추가 데이터 시각화입니다.우리의 고객 기반은 수천 명에 달하므로 설치할 때마다 타사 공급업체의 테이블을 수정하도록 요구하고 싶지 않습니다.

에 의해 "테이블 변경" 내 말은 테이블 구조의 변경이 아니라 테이블 데이터의 변경을 의미합니다.

궁극적으로 나는 일정 간격으로 변경 사항을 확인하는 대신 내 애플리케이션에서 이벤트를 트리거하는 변경을 원합니다.


내 요구 사항(트리거 또는 스키마 수정 없음, SQL Server 2000 및 2005)을 고려할 때 최선의 조치는 다음을 사용하는 것 같습니다. BINARY_CHECKSUM 기능하다 T-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(순환 중복 검사) 계산은 없습니다.

따라서 모든 변경 사항을 감지하는 데 사용할 수 없습니다.g.대칭적인 변경으로 인해 동일한 CHECKSUM이 생성됩니다!

이자형.g.해결책 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!

(binary_checksum (*))에서 checksum_agg (binary_checksum (*))를 선택하십시오 (numa로 1을 선택하고, 2는 numb an select 1 as 1 as numa, 2 as numb) q- 전달 0!

Checksum_agg (binary_checksum (*))를 선택하십시오 (NUMA로 0을 선택하고 0은 numb Union All All 0 AS NUMA, 0 AS NUMB) Q- 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 뷰를 모니터링합니다.

여기에서 추측해 보세요:타사의 테이블을 수정하고 싶지 않은 경우 뷰를 만든 다음 해당 뷰에 트리거를 넣을 수 있나요?

마지막 커밋 날짜를 확인하세요.모든 데이터베이스에는 각 커밋이 이루어진 시점에 대한 기록이 있습니다.나는 그것이 ACID 준수의 표준이라고 믿습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top