2012-08-08 3 views
12

SQL Server 2012에서 행 집합과 열 집합의 해시를 생성하는 방법이 있습니까?SQL 서버에서 행 집합에 대한 해시 생성

해시를 생성하여 상위 레코드에 저장하려고합니다. 업데이트가 들어 오면 들어오는 해시를 상위 레코드 해시와 비교하고 데이터가 변경되었는지 여부를 알 수 있습니다.

그래서 이런 일이 좋은 것 :

SELECT GENERATEHASH(CONCATENATE(Name, Description, AnotherColumn)) 
FROM MyChildTable WHERE ParentId = 2 -- subset of data belong to parent record 2 

는 "연결하여"집계 함수가 될 것이다 것뿐만 아니라 열 CONCAT뿐만 아니라, 결과 집합 내부의 행. MAX와 비슷하지만 모든 것을 문자열 연결로 반환합니다.

이 정보가 도움이 되었기를 바랍니다.

내가 해결하려고하는 근본적인 문제는 클라이언트의 시스템이 방대한 양의 계층 적 데이터를 가져 오는 것입니다. 해시를 사용하여 처리하지 않아도된다면 많은 시간을 절약 할 수 있다고 생각합니다. 현재 SP는 중복 데이터를 처리해야 할 때 300 % 느리게 실행됩니다.

많은 감사 한 행 해시를 들어

답변

10

당신은 CHECKSUM_AGG 집계를 사용할 수 있습니다. 그것은 그 목적을 위해 만들어진 것입니다.

+4

불행히도 CHECKSUM에는 약점 (예 : 실제 충돌)이 있습니다. 예 : decimal type http://sqlserverpains.blogspot.com.au/2008/06/checksum-pains.html 참고하시기 바랍니다. – Shiv

1

: 테이블 검사에 대한

select HASHBYTES('md5', Name + Description + AnotherColumn) 
FROM MyChildTable WHERE ParentId = 2 

는 :

select sum(checksum(Name + Description + AnotherColumn)*1.0) 
FROM MyChildTable WHERE ParentId = 2 
+0

이합니까 전체 결과 집합에서 해시를 생성 하시겠습니까? 또는 MyChildTable의 각 행에 하나씩 여러 개의 해시가 생성됩니까? – krisdyson

+0

내 편집의 두 번째 해결 방법을 시도해보십시오. –

+0

정수가 넘치지 않도록 다시 업데이트되었습니다. –

1

또 다른 방법 :

-- compute a single hash value for all rows of a table 
begin 

    set nocount on; 

    -- init hash variable 
    declare @tblhash varchar(40); 
    set @tblhash = 'start'; 

    -- compute a single hash value 
    select @tblhash = sys.fn_varbintohexsubstring(0, hashbytes('sha1',(convert(varbinary(max),@tblhash+ 
    (select sys.fn_varbintohexsubstring(0,hashbytes('sha1',(convert(varbinary(max), 
    -- replace 'select *' if you want only specific columns to be included in the hash calculation 
    -- [target table] is the name of the table to calc the hash from 
    -- [row_id] is the primary key column within the target table 
    -- modify those in the next lines to suit your needs: 
    (select * from [target_table] obj2 where obj2.[row_id]=obj1.[row_id] for xml raw) 
    ))),1,0)) 
    ))),1,0) 
    from [target_table] obj1; 

    set nocount off; 

    -- return result 
    select @tblhash as hashvalue; 

end; 
9
select HashBytes('md5',convert(varbinary(max),(SELECT * FROM MyChildTable WHERE ParentId = 2 FOR XML AUTO))) 

하지만 HashBytes 당신이 모든 8000 바이트 드 MD5를 얻을 수있는 기능을 만들 수 있습니다 ... 만 8000 바이트로 제한됩니다 ....

+0

일부 JSON 지원이있는 SQL Server 2016 이상을 사용하는 경우 FOR XML AUTO 대신 FOR JSON AUTO를 사용하는 것이 좋습니다. 몇 번의 테스트에서 약 2 배 빠르기 때문입니다. – Isak

관련 문제