2013-05-09 38 views
9

是否有一種「半可移植」方式來獲取整行的md5()或sha1()? (或者更好的是,在他們的所有領域排序的整組行中,即order by 1,2,3,...,n)?不幸的是,並不是所有的數據庫都是PostgreSQL ......我必須處理至少微軟的SQL服務器,Sybase和Oracle。獲取整行MD5或SHA1的SQL方法

理想情況下,我想有一個聚合器(服務器端),並使用它來檢測行組中的更改。例如,在有一些時間戳列的表中,我想爲每個月存儲一個唯一的簽名。然後,我可以快速檢測自上次訪問(我將某些表映射到運行Greenplum的服務器)以來發生變化的月份,並重新加載這些月份。

我看過幾個選項,例如checksum(*)在TSQL(恐怖:它是非常易於衝突的,因爲它是基於一串異或和32位值),並且hashbytes('MD5', field),但後者不能被施加到一整行。這將給我一個解決方案,只是我必須處理的SQL風格之一。

有什麼想法?即使只是上面提到的SQL成語中的一個,那也是很棒的。

回答

8

你可以計算整個行HASHBYTES值上一個更新觸發器,我就以此爲那些之前在表中比較所有列的ETL過程的一部分,速度的提升是巨大的。

HASHBYTES適用於VARCHAR,nvarchar或varbinary數據類型,我想比較整數鍵和文本字段,鑄造一切都將是一個噩夢,所以我用FOR XML子句在SQL服務器如下:

CREATE TRIGGER get_hash_value ON staging_table 
FOR UPDATE, INSERT AS 
UPDATE staging_table 
SET sha1_hash = (SELECT hashbytes('sha1', (SELECT col1, col2, col3 FOR XML RAW))) 
GO 

或者,你可以以類似的方式,如果你計劃使用子查詢與FOR XML子句也做的所有行多次更新計算值觸發之外。如果走這條路線,你甚至可以將它改爲SELECT *,但不是在觸發器中,因爲每次運行它時,都會得到不同的值,因爲每次sha1_hash列都會有所不同。

您可以修改select語句獲得超過1行

3

在MSSQL中 - 您可以通過使用XML使用整個行HASHBYTES ..

SELECT MBT.id, 
    hashbytes('MD5', 
       (SELECT MBT.* 
       FROM (
         VALUES(NULL))foo(bar) 
       FOR xml auto)) AS [Hash] 
FROM <Table> AS MBT; 

您需要from (values(null))foo(bar)子句使用xml自動,它沒有其他用途..