2012-03-07 67 views
14

Tôi đang viết một hàm trả về bảng. Có hai tham số được truyền cho hàm và truy vấn được xây dựng và thực thi và được chèn vào bảng trả về. Tuy nhiên tôi nhận được lỗi này.Gọi SQL động từ hàm

Chỉ có thể thực hiện các chức năng và một số quy trình được lưu trữ mở rộng từ bên trong một hàm.

Tôi không muốn sử dụng quy trình được lưu trữ vì đây là một chức năng tiện ích đơn giản. Có ai biết nếu điều này có thể được thực hiện. Hàm của tôi được mã hóa dưới đây, nó sẽ kiểm tra các lỗi cho một cột nhất định trong một bảng nhất định.

-- ============================================= 
-- AUTHOR:  JON AIREY 
-- THIS FUNCTION WILL RETURN A COUNT OF HOW MANY 
-- TIMES A CERTAIN COLUMN VALUE APPEARS IN A 
-- TABLE. THIS IS HELPFUL FOR FINDING DUPES. 

-- THIS FUNCTION WILL ACCEPT A COLUMN NAME, TABLE 
-- NAME (MUST INCLUDE SCHEMA), AND OPTIONAL 
-- DATABASE TO USE. RESULTS WILL BE RETURNED AS 
-- A TABLE. 
-- ============================================= 
ALTER FUNCTION [dbo].[fn_FindDupe] 
( 
-- Add the parameters for the function here 
@Column  VARCHAR(MAX), 
@Table  VARCHAR(100), 
@Database VARCHAR(100) = '' 
) 
RETURNS 
@TempTable TABLE 
     ([Column] varchar(100) 
     ,[Count] int) 
AS 
BEGIN 
    DECLARE @SQL VARCHAR(MAX) 
    SET @Table = CASE 
         WHEN @Database = '' 
         THEN @Table 
         ELSE @Database + '.' + @Table 
        END 

    SET @SQL = 

    ' 
     INSERT INTO @TempTable 

     SELECT  ' + @Column + ' 
        ,COUNT(' + @Column + ') AS CNT 
     FROM  ' + @Table + ' 
     GROUP BY ' + @Column + ' 
     ORDER BY CNT DESC 
    ' 

    EXEC SP_EXECUTESQL @SQL 

RETURN 
END 
GO 

Trả lời

21

You can't use dynamic sql in a udf:

này rất đơn giản: bạn không thể sử dụng SQL động từ sử dụng xác định chức năng viết bằng T-SQL. Điều này là do bạn không được phép làm bất kỳ thứ gì trong UDF có thể thay đổi trạng thái cơ sở dữ liệu (vì UDF có thể được gọi là một phần của truy vấn). Vì bạn có thể làm bất cứ điều gì từ SQL động , bao gồm các bản cập nhật, rõ ràng là tại sao SQL động không được cho phép .

...

Trong SQL 2005 và sau đó, bạn có thể thực hiện chức năng của mình như một CLR chức năng. Nhớ lại rằng tất cả truy cập dữ liệu từ CLR là SQL động. (Bạn được bảo vệ an toàn, để nếu bạn thực hiện thao tác cập nhật từ chức năng của mình, bạn sẽ bị bắt.) Cảnh báo mặc dù: dữ liệu truy cập từ UDF vô hướng thường có thể gây ra sự cố hiệu suất.

+0

Tôi làm cách nào để thực hiện chức năng CLR này? – JBone

+0

[Cách thực hiện: Tạo và chạy một hàm máy chủ SQL do người dùng định nghĩa] (http://msdn.microsoft.com/en-us/library/w2kae45k (v = vs.80) .aspx) –

+1

'Vì bạn có thể làm bất cứ điều gì từ SQL động, bao gồm các bản cập nhật, rõ ràng là tại sao SQL động không được phép. ', đó là chính xác. Nhưng đồng thời bạn phải phân tích cú pháp sql động của bạn với ví dụ. sp_executesql(), vì vậy SQL Server có mọi khả năng để bắt các truy vấn thay đổi dữ liệu và cho phép người khác vượt qua. Vì vậy, là lý do thực sự - họ không bận tâm để thực hiện nó? –