我有以下SQL函数:
create function [dbo].[LookUpAnonymiseString](@string varchar(500), @tableSize int)
returns varchar(500)
as
begin
DECLARE @output varchar(500)
SELECT @output = Value FROM AnonymisationLookup.dbo.Forename WHERE AnonymisationLookup.dbo.Forename.ID = ABS(CHECKSUM(@string)) % @tableSize
return @output
end
go
我相信这个函数工作正常,它需要一个输入字符串和int表示一个查找表的大小(包含所有可用的字符串)。然后我将输入字符串哈希到索引中以查找表,并在该索引处返回输出字符串的值。
我想概括函数,以便可以在查询中传入和使用表的名称,而不是硬编码的“Forename”表。
我尝试了以下内容,但SQL抱怨并说“只能在函数内执行函数和一些扩展存储过程。”
create function [dbo].[LookUpAnonymiseString](@string varchar(500), @tableName varchar(128), @tableSize int)
returns varchar(500)
as
begin
declare @output varchar(500)
declare @sql nvarchar(max)
set @sql = N'select @output = Value from AnonymisationLookup.dbo.'+quotename(@tableName)+' where AnonymisationLookup.dbo.'+quotename(@tableName)+'.ID = abs(checksum(@string)) % @tableSize'
exec sp_executesql @sql, N'@output nvarchar(max) out', @output out
return @output
end
go
答案 0 :(得分:1)
您的第一个查询“有点”有效。只有在ID中没有间隙时它才有效 - 并且id很容易产生间隙(甚至是identity
列)。所以更安全的方法是:
DECLARE @output varchar(500);
SELECT TOP 1 @output = Value
FROM AnonymisationLookup.dbo.Forename f
WHERE F.ID >= ABS(CHECKSUM(@string)) % @tableSize
ORDER BY F.ID;
return @output;
然后,你传递表的目标不能在一个函数中完成(除非是一个非常复杂,深奥的方式)。因此,你真的不能做你想做的事。您可以在存储过程中使用动态SQL,但不能直接在函数中使用。