web-dev-qa-db-ja.com

関数から動的SQLを呼び出す

テーブルを返す関数を書いています。関数に渡される2つのパラメーターがあり、クエリが作成されて実行され、返されるテーブルに挿入されます。ただし、このエラーが発生します。

関数内から実行できるのは、関数と一部の拡張ストアドプロシージャだけです。

これは単純なユーティリティ関数なので、ストアドプロシージャは使用しません。これができるかどうか誰かが知っていますか?私の関数は以下にコード化されています、それは特定のテーブル内の特定の列の重複をチェックします。

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

DFでは動的SQLを使用できません

これは非常に簡単です。T-SQLで記述された定義済み関数から動的SQLを使用することはできません。これは、データベースの状態を変更する可能性のあるUDFでの実行が許可されていないためです(UDFはクエリの一部として呼び出される可能性があるため)。更新を含め、動的SQLから何でもできるため、動的SQLが許可されない理由は明らかです。

.。

SQL 2005以降では、関数をCLR関数として実装できました。 CLRからのすべてのデータアクセスは動的SQLであることを思い出してください。 (安全に保護されているため、関数から更新操作を実行すると、捕まる可能性があります。)ただし、警告の言葉:スカラーUDFからのデータアクセスは、パフォーマンスの問題を引き起こすことがよくあります。

24