2012-08-08 23 views
12

SQL Server 2012'de bir dizi satır ve sütun karması oluşturmak için herhangi bir yol var mı?sql sunucusunda bir dizi satır için karma üret

Bir karma oluşturmak istiyorum, üst kayıtta saklayın. Bir güncelleme geldiğinde, gelen karma ile ana kayıt karma değerini karşılaştırırım ve verilerin değişip değişmediğini öğreneceğim.

Yani böyle bir şey iyi olurdu:

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

"BİRLEŞTİR" bir toplama işlevi olacağını olmaz sadece sütunlar concat, aynı zamanda, resultset içindeki satırlar. MAX gibi, ancak her şeyi bir dizge birleştirme olarak döndürüyor.

Umarım bu ne demek istediğimi görmenize yardımcı olur!

Çözmeyi denediğim temel sorun, istemcimin sistemindeki çok miktarda hiyerarşik veri ithalatını gerçekleştirmesidir. Eğer karma kullanımıyla işlenmeyi engelleyebilirsem, bunun çok zaman kazandıracağını düşünürdüm. Şu anda, SP, yinelenen verileri işlemek zorunda kaldığında% 300 daha yavaş çalışıyor.

çok teşekkürler tek sıra sağlamalarının için

cevap

10

Sen CHECKSUM_AGG agrega kullanabilirsiniz. bu amaçla yapılır.

+4

Ne yazık ki CHECKSUM bilinen zayıflıklara (yani pratik çarpışmalara) sahiptir. Örneğin. ondalık türü http://sqlserverpains.blogspot.com.au/2008/06/checksum-pains.html bu yüzden sadece dikkat edin. – Shiv

1

: Tablo toplamı için

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

bu mu tüm resultset bir karma üretmek? Yoksa MyChildTable'ta her satır için birden fazla karma üretecek mi? – krisdyson

+0

Düzenlememdeki 2. çözümü deneyin. –

+0

Tamsayı taşmasını önlemek için tekrar güncellendim. –

1

başka bir yaklaşım:

-- 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))) 

ama HashBytes her 8000 bayt için de MD5 almak için bir işlev yapabilir ... sadece 8000 byte ile sınırlıdır ....

+0

Bazı JSON desteğine sahip olan SQL Server 2016 veya üzerindeyseniz, 'IÇIN XML AUTO 'yerine JSON AUTO'yu kullanmanızı öneririm, çünkü yaptığım birkaç testte yaklaşık 2 kat daha hızlı görünüyor. – Isak

İlgili konular