2017-06-16 64 views
1

我有以下SQL功能的SQL表查找功能:要概括执行exec

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 
+1

您不能从函数执行存储过程。用存储过程替换函数可能是解决方案。 – Peter

+0

谢谢彼得。可能会调查这些 – dahui

回答

1

您的第一个查询“sort of”works。它只有在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,但不能直接在函数中使用。

+0

我已经给你提供了评论的赞成票,但是我的表格是即时生成的,所以我不认为ID会成为问题。感谢您的反馈 – dahui

+0

@dahui,你有没有试过这个答案(一个建立所需SQL语句并使用'sp_executesql'执行的存储过程),还是你坚持使用? –

+0

@DanGuzman。 。 。您不能在存储的函数中调用存储过程。 。 。除非你去操作系统并连接回SQL Server。 –