2013-03-02 28 views
14

Tôi tạo một hàm để thực thi SQL động và trả về một giá trị. Tôi nhận được "Chỉ có các hàm và một số thủ tục được lưu trữ mở rộng mới có thể được thực thi từ bên trong một hàm." như một lỗi.Nhận lỗi khi thực thi sql động trong một hàm (SQL Server)?

Chức năng:

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 

Việc thực hiện:

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

và:

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

Sản phẩm chức năng được gọi là đúng hay là chức năng không chính xác?

Trả lời

7

Bạn không thể sử dụng SQL động từ một hàm, bạn cũng không thể gọi các thủ tục được lưu trữ .

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

Cảm ơn bạn Alexandria, rất biết ơn !!!!!!! – Chaka

+0

BTW, để ngăn chặn SQL Injection sử dụng sp_executesql với tham số –

0

Tôi không nghĩ rằng bạn có thể sử dụng SQL động từ một hàm, cũng như tôi nghĩ bạn cần trong trường hợp của mình. Trông giống như bạn muốn một cái gì đó gần gũi hơn với điều này:

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

Ngoài ra, hãy kiểm tra kiểu dữ liệu của bạn để đảm bảo rằng bạn lĩnh vực là chính xác. Có vẻ kỳ quặc để vượt qua trong một varchar cho id và trả về một int cho lĩnh vực khác. Dù bằng cách nào, điều này sẽ giúp bạn đi đúng hướng.

1

Các chức năng bị giới hạn trong những gì chúng có thể sử dụng, để bạn có thể sử dụng chúng trong truy vấn mà không vô tình tạo ra thứ gì đó mang lại hiệu suất kinh khủng. Sử dụng các truy vấn động là một trong những điều đó, vì điều đó sẽ gây ra một kế hoạch truy vấn cho mỗi lần thực hiện, và cũng sẽ giữ cho hàm không thể là một phần của kế hoạch truy vấn.

Bạn không cần phải truy vấn động ở tất cả các trường hợp này, chỉ cần trả về giá trị:

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

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

end 
Các vấn đề liên quan