从函数调用动态SQL

JBo*_*one 16 sql t-sql function dynamic

我正在编写一个返回表的函数.有两个参数传递给函数,构建并执行查询并将其插入到返回表中.但是我收到了这个错误.

只能在函数内执行函数和一些扩展存储过程.

我想不使用存储过程,因为这是一个简单的实用功能.有谁知道这是否可以做到.我的函数在下面编码,它检查某个表中某个列的dupe.

-- =============================================
-- 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
Run Code Online (Sandbox Code Playgroud)

Mic*_*son 23

你不能在udf中使用动态sql:

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

...

在SQL 2005及更高版本中,您可以将您的函数实现为CLR函数.回想一下,CLR的所有数据访问都是动态SQL.(你是安全保护的,所以如果你从你的函数执行更新操作,你就会被抓住.)尽管如此警告:来自标量UDF的数据访问通常会带来性能问题.

  • "由于你可以从动态SQL做任何事情,包括更新,很明显为什么不允许动态SQL.",这是正确的.但同时你必须用例如解析你的动态sql.sp_executesql(),因此SQL Server有可能捕获数据更改查询并让其他人通过.真正的原因是什么 - 他们没有费心去实施它? (2认同)