2013-09-26 47 views
0

我想在T-SQL中創建一個類似於Java中的標量函數。在T-SQL中爲字符串實現GetHashCode

在命令式語言的標準實現是:

int hash = 0; 
for (int i = 0; i < length; i++) 
{ 
    hash = 31*hash + value[i]; 
} 
return hash; 

我不是真的在TSQL好實現這一點,從我的POV寫命令式的代碼在TSQL的東西,應該是避免。我想這可以使用CTE完成?請問=)

另外,我可以使它始終是積極的,即當結果超過integrer max,那麼它流過0而不是整數min?讓我們假設可能的參數數量(我的解決方案中特殊類的數量)並不是很大。假設它永遠不會超過1000,所以我相信在這裏即使使用uint也能避免碰撞。


PS:如果有人interesed什麼,我需要這個了,比我能解釋一下,大概你能提出更好的解決方案。我有一個integer標識列和varchar'TypeFullName'表 - 這是我們C#解決方案中類的全名。

我需要編寫一個腳本,手動設置ID爲TypeFullName(是的,打開SET IDENTITY INSERT選項)的函數依賴關係。這樣我可以計算ID,如果我知道類型名稱。我知道這聽起來像一個設計不好的系統,它可能是,但相信我,我現在只需要這樣做)

謝謝!

回答

0

我發現在internet的解決方案,並稍微更新它的輸出限制爲陽性:

begin 
declare @h bigint 
set @h = 0 
select @h = (@h*31 + ascii(substring(@str,X.pos,1)))%4294967296 
    from (select top(len(@str)) 
      row_number() over (order by getdate()) as pos 
      from sys.all_objects) as X 
if @h >= 2147483647 set @h = @h - 2147483647 
return convert(int, @h) 
end; 

select top from sys.all_objects真的哈克,但(((至少它的作品。

+0

row_number()over是一個TALLY表。有關更多詳細信息,請參閱Jeff Moden。基本上它是交叉的數字表格。因此,您正在查看每個字符並應用轉換。 –

+0

是的,我知道它是如何工作的,只會列出值1..n,所以它有點像迭代器一樣工作。我的意思是,它看起來像一個黑客) –

+0

唯一的選擇是創建一個表[msdb]。[dbo]。[Tally]並加載1 M行或您可能使用的最大迭代器。將[msdb]。[dbo]。[Tally])中的代碼更改爲'(SELECT TOP(LEN(@str)))爲X'。 Tally表假定比WHILE循環更快。但看起來很有趣,因爲它引用了sys.all_objects。 (HACK) –

1

閱讀關於CheckSum與Hashbytes的文章。 (http://craftydba.com/?p=3005

它們是兩個內置的SQL Server函數,它們將生成一個給定值的哈希鍵。一個比另一個更獨特。

如果您仍然有疑問,只需詢問。

真誠

約翰

www.craftydba.com

PS:

強制轉換爲int或大INT當你失去精度。只需將它保存爲一個GUID(16字節十六進制)。

enter image description here

+0

嗨!我想過使用MD5,但我需要限制輸出爲正整數。=) 使用descibed hashcode算法更容易 - 只要做'hash = hash%(2^32)'at每次迭代和t如果(hash> 2147483647){hash- = 2147483647; }'。 (我猜這樣的事情......) –

+0

並且對於MD5哈希,我不能做任何事情,對於inst,我應該怎麼做,用convert(int,HashBytes('MD5','test1'))'?它給了我-1574543990。 –

+0

除了第一條評論:在這種情況下,我會從long(sql-server中的bigint)開始,然後在返回之前將其轉換爲int。 –