2017-06-16 60 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。 –