2012-01-10 86 views
4

是否可以從兩個數據庫服務器生成哈希代碼並進行比較?如何在SQL Server中編寫以下僞SQL?尤其是兩個getHash函數接受SQL服務器和oracle中的多重數字/浮點列。從SQL Server和Oracle獲取散列值並進行比較?

select s.PK 
from sqltable s 
    join openquery(oracleLinkedServer, 
     'select PK, getHash(Column1, floatColumn2, ..., floatColumnN) oracleHash 
     from oracleTable') o on o.PK = s.PK 
where 
    getHash(Column1, floatColumn2, ..., floatColumnN) <> oracleHash 
+2

鑑於SQL Server和Oracle之間的許多數據類型不可能具有100%的匹配表示,所以它不太可能工作 – 2012-01-11 07:48:52

+0

如果將所有值轉換爲大字符串(x,1.234,2.345 =「x1」),它可能會工作。 2342.345「),然後根據相同的編碼計算散列(例如md5)。 – tbone 2012-01-11 13:20:13

+0

@tbone將它們連接到一個大的字符串可能會引入更多的不確定性。 – ca9163d9 2012-01-11 17:01:16

回答

9

在SQL Server:

select upper(substring(sys.fn_sqlvarbasetostr(hashbytes('MD5','A')),3,32)); 

結果:

7FC56270E7A70FA81A5935B72EACBE29 

在Oracle:

select rawtohex(
    DBMS_CRYPTO.Hash (
     UTL_I18N.STRING_TO_RAW ('A', 'AL32UTF8'), 
     2) 
    ) from dual; 

結果:

7FC56270E7A70FA81A5935B72EACBE29 

確保您的字符串完全相同(區分大小寫)。在這裏我使用'A'作爲一個簡單的例子,但它可以是任何字符串。

如果通過轉換爲大字符串避免數據類型差異,則應該能夠在不同平臺上生成相同的md5散列。請注意,SQL Server將前綴'0x'用於表示十六進制表示,我用子字符串剝離它。

+0

謝謝。在我的情況下,我已經改變了Oracle的AL16UTF16LE的AL32UTF8,並將MS SQL端的文本轉換爲nvarchar(cast('ĄĘA'as nvarchar(max)),但無論如何,非常感謝。 – eye 2014-03-18 13:31:43

+0

如何獲得散列整行而不只是列? – Aravindh 2014-06-02 20:23:17

+0

@Aravindh你可以連接字符串,但它聽起來像你想要一個獨特的散列/編號的行,這意味着你應該看看[sys_guid](http://stackoverflow.com/questions/11864575 /應該我使用oracles-sys-guid生成GUID/11865036)#11865036) – tbone 2014-06-03 01:30:37

3

在SQL Server中,您有hashbytes();在Oracle中你有DBMS_CRYPTO.Hash()。你應該可以使用它們來計算雙方的MD5哈希值,但我不太肯定哈希值會匹配......它值得一試。

還有其他方法可以比較表,但要回答您的問題,這些是兩個平臺上的兩個本地功能。

+0

這兩個函數不接受多列,所以用戶必須將多列組合成一列。是的,正如你所提到的那樣,即使它們的值相同,也不確定哈希值是否匹配,特別是對於這些浮點數。 – ca9163d9 2012-01-11 06:21:02

+0

@NickW如果你想在同一時間對多個列進行散列,在Oracle上你可以使用DBMS_SQLHASH:http://docs.oracle.com/cd/B19306_01/network.102/b14266/appendixb.htm但是我認爲這個包非常不可能匹配SQL Server的任何輸出。 – 2012-01-12 04:54:59

0

您可以在SQL Server中使用CHECKSUM()來計算多列哈希。