2013-03-02 119 views
14

我創建一個函數來執行動態SQL並返回一個值。我得到「只有函數和一些擴展存儲過程可以在函數內執行。」作爲錯誤。在函數內執行動態SQL時獲取錯誤(SQL Server)?

功能:

Create Function fn_GetPrePopValue(@paramterValue nvarchar(100)) 
returns int as 
begin 
declare @value nvarchar(500); 

Set @SQLString = 'Select Grant_Nr From Grant_Master where grant_id=' + @paramterValue 

exec sp_executesql 
     @query = @SQLString,  
     @value = @value output 

return @value 
end 

執行:

Select dbo.fn_GetPrePopValue('10002618') from Questions Where QuestionID=114 

和:

Select fn_GetPrePopValue('10002618') from Questions Where QuestionID=114 

的功能是可以正確呼叫或者是不正確的功能?

回答

7

您不能使用函數中的動態SQL,也不能調用 存儲過程。

Create proc GetPrePopValue(@paramterValue nvarchar(100)) 
as 
begin 
declare @value nvarchar(500), 
     @SQLString nvarchar(4000) 

Set @SQLString = 'Select @value = Grant_Nr From Grant_Master where grant_id = @paramterValue' 

exec sp_executesql @SQLString, N'@paramterValue nvarchar(100)', 
     @paramterValue, 
     @value = @value output 

return @value 
end 
+0

謝謝亞歷山大,非常感謝!!!!!!! – Chaka 2013-03-02 23:33:21

+0

BTW,用於防止SQL注入使用帶參數的sp_executesql – 2013-03-02 23:37:38

0

我不認爲你可以使用動態SQL從一個功能,我也不認爲你需要你的情況。看起來你想要的東西更接近這個:

Create Function dbo.fn_GetPrePopValue(@paramterValue nvarchar(100)) 
returns int as 
begin 
    declare @value int 
    declare @SQLString varchar(MAX) 

    Select @value=Grant_Nr From Grant_Master where [email protected] 

    return @value 
end 

SQL Fiddle Demo

另外,請檢查您的數據類型,以確保你的領域是正確的。似乎奇數傳入一個varchar爲id並返回一個int爲其他字段。無論哪種方式,這應該有助於你朝着正確的方向前進。

1

函數的用途是有限的,所以你可以在查詢中使用它們,而不會不小心做出可怕的表現。使用動態查詢就是其中之一,因爲這會導致每次執行的查詢計劃,並且還會使該函數無法成爲查詢計劃的一部分。

你不需要動態查詢所有在此情況下,只返回值:

Create Function fn_GetPrePopValue(@paramterValue nvarchar(100)) 
returns int as 
begin 

return (select Grant_Nr From Grant_Master where grant_id = @paramterValue) 

end