2012-03-07 100 views
14

我在写一个返回表的函数。有两个参数传递给函数,并且构建和执行查询并将其插入到返回的表中。但是,我收到此错误。从函数调用动态SQL

只有函数和一些扩展存储过程可以从函数内部执行。

我想不使用存储过程,因为这是一个简单的实用函数。有谁知道这是否可以做到。我的函数编码如下,它检查某个表内特定列的模糊。

-- ============================================= 
-- 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 

回答

21

You can't use dynamic sql in a udf

这很简单:你不能使用动态SQL从使用的定义写在T-SQL 功能。这是因为您不允许在UDF中执行任何可能会更改数据库状态的任何内容(因为UDF可能会将 作为查询的一部分进行调用)。由于您可以执行任何动态SQL,包括更新,因此很明显为什么动态SQL不允许使用 。

...

在SQL 2005及更高版本,你可以实现你的功能为CLR 功能。回想一下,CLR的所有数据访问都是动态SQL。 (你是安全的,所以如果你执行从你的功能 更新操作,你会被抓住。)一个警告虽然:数据 访问标量UDF往往可以给性能问题。

+0

我该如何使这个CLR函数? – JBone 2012-03-07 19:51:38

+0

[如何创建和运行CLR SQL Server用户定义的函数](http://msdn.microsoft.com/zh-cn/library/w2kae45k(v = vs80).aspx) – 2012-03-07 19:58:25

+1

'既然你可以做任何动态SQL,包括更新,很明显为什么不允许动态SQL。“,这是正确的。但同时你必须用例如解析你的动态sql。 sp_executesql(),因此SQL Server可以捕获数据更改查询并让其他人通过。 所以才是真正的原因 - 他们没有打算实施它? – 2017-08-11 11:43:07