我想在T-SQL中创建一个类似于Java中的标量函数。
命令式语言的标准实现是:
int hash = 0;
for (int i = 0; i < length; i++)
{
hash = 31*hash + value[i];
}
return hash;
我在tsql中实现这一点并不是那么好,而且从我的POV编写t-sql中的命令式代码是应该避免的。我想这可以用CTE完成吗?请=)
另外,我可以使它始终是positivie,即当结果超过integrer max时,它会流过0而不是整数min吗?让我们假设可能的参数数量(我的解决方案中特殊类的数量)并不是很大。假设它永远不会超过1000,所以我确信即使使用uint也可以避免碰撞。
PS:如果有人对我需要的东西感兴趣,那么我可以解释一下,可能你可以建议一个更好的解决方案。我有一个包含integer
标识列和varchar
列'TypeFullName'
的表格 - 这是我们C#解决方案中类的全名。
我需要编写一个脚本,将手动设置ID作为TypeFullName
的函数依赖(是的,打开SET IDENTITY INSERT
选项)。如果我知道类型名称,那么我可以计算ID。我知道这听起来像一个设计糟糕的系统,它可能是,但相信我,我现在必须这样做)
谢谢!
答案 0 :(得分:1)
阅读关于CheckSum与Hashbytes的文章。 (http://craftydba.com/?p=3005)
它们是两个内置的SQL Server函数,它们将为您生成给定值的哈希键。一个比另一个更独特。
如果您仍有疑问,请询问。
此致
约翰
www.craftydba.com
PS:
在转换为int或big int时,您正在失去精度。只需将其保存为GUID(16字节十六进制)。
答案 1 :(得分: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
真的很骇客,但是(((至少它有效。