在我的sql server表中,我想添加一个计算列,它是同一个表中其他列的哈希值。下面是我的表结构。
地址:
地址ID(int,PK)
AddressLine1(nvarchar)
AddressLine2(nvarchar)
城市(nvarchar)
州(nvarchar)
AddressHash(计算列)
以下是我想在计算列中得到的内容:
MASTER.SYS.FN_VARBINTOHEXSUBSTRING(0, HASHBYTES('SHA1',COALESCE(AddressLine1, N'') + COALESCE(AddressLine2, N'') + COALESCE(City, N'') + COALESCE(State, N'')), 1, 0)
如果我右键单击该表并进行设计并在“计算列规范”下输入上面的“公式”,我会收到以下错误:
- 无法修改表格 在此上下文中,用户定义的函数名称不能以数据库名称为前缀。
所以我想我会使用用户定义的函数来计算哈希并将udf映射到公式。
以下是我用来创建UDF的代码:
CREATE FUNCTION udfHashAddress
(
@pAddressLine1 nvarchar(50), @pAddressLine2 nvarchar(50), @pCity nvarchar(50), @pState nvarchar(50))
)
RETURNS nvarchar(max) -- not sure what the correct size would be
WITH SCHEMABINDING
AS
BEGIN
DECLARE @result nvarchar(max)
SELECT @result = MASTER.SYS.FN_VARBINTOHEXSUBSTRING(0, HASHBYTES('SHA1',COALESCE(@pAddressLine1, N'') + COALESCE(@pAddressLine2, N'') + COALESCE(@pCity, N'') + COALESCE(@pState, N'')), 1, 0)
RETURN @result
END
GO
但是我在上面的代码中遇到以下错误:
* 无法架构绑定函数'udfHashAddress',因为名称'MASTER.SYS.FN_VARBINTOHEXSUBSTRING'对于架构绑定无效。名称必须采用两部分格式,对象不能引用自身。*
当我删除“MASTER”数据库前缀时,出现此错误:
* 无法模式绑定函数'udfHashAddress',因为它引用了系统对象'SYS.FN_VARBINTOHEXSUBSTRING'。*
我在这里遗漏了什么吗?非常感谢任何帮助/指针。
答案 0 :(得分:6)
由于您使用的是SQL Server 2008,您是否尝试过:
CONVERT(VARCHAR(MAX), HASHBYTES('SHA1','string'), 2);
这将返回大写字母而不是小写字母,但如果它很重要,你可以用LOWER()来修复它。
以下是您的实际架构(有意在tempdb中创建)的示例:
USE tempdb;
GO
CREATE TABLE dbo.[Address]
(
AddressID INT PRIMARY KEY,
AddressLine1 NVARCHAR(64),
AddressLine2 NVARCHAR(64),
City NVARCHAR(64),
[State] NVARCHAR(64),
AddressHash AS LOWER(CONVERT(VARCHAR(4000), HASHBYTES('SHA1',
COALESCE(AddressLine1, N'') + COALESCE(AddressLine2, N'')
+ COALESCE(City, N'') + COALESCE([State], N'')), 2))
--PERSISTED -- you could also persist it if desired
);
INSERT dbo.[Address]
VALUES(1, 'foo', 'bar', 'blat', 'splunge'),
(2, 'bar', 'foo', 'blag', 'splmger');
SELECT *, master.dbo.fn_varbintohexsubstring
(0,
HASHBYTES
(
'SHA1',
COALESCE(AddressLine1, N'') + COALESCE(AddressLine2, N'')
+ COALESCE(City, N'') + COALESCE([State], N'')
), 1, 0)
FROM dbo.[Address];
GO
DROP TABLE dbo.[Address];