Вызов динамического SQL из функции - PullRequest
16 голосов
/ 07 марта 2012

Я пишу функцию, которая возвращает таблицу.Есть два параметра, которые передаются в функцию, и запрос строится и выполняется и вставляется в возвращаемую таблицу.Однако я получаю эту ошибку.

Из функции могут быть выполнены только функции и некоторые расширенные хранимые процедуры.

Я бы не хотел использовать хранимую процедуру, поскольку это простая служебная функция.Кто-нибудь знает, можно ли это сделать?Моя функция написана ниже, она проверяет наличие ошибок для определенного столбца в определенной таблице.

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

1 Ответ

23 голосов
/ 07 марта 2012

Вы не можете использовать динамический sql в udf :

Это очень просто: вы не можете использовать динамический SQL из определенных функции, написанные на T-SQL. Это потому, что вам не разрешено делать что-нибудь в UDF, которое может изменить состояние базы данных (как UDF может вызываться как часть запроса). Так как вы можете сделать что-нибудь из динамического SQL, включая обновления, очевидно, почему динамический SQL не допускается.

...

В SQL 2005 и более поздних версиях вы можете реализовать свою функцию в виде CLR функция. Напомним, что весь доступ к данным из CLR является динамическим SQL. (Вы в безопасности, так что если вы выполняете операцию обновления из Ваша функция, вы будете пойманы.) Хотя слово предупреждения: данные доступ из скалярных UDF часто может вызвать проблемы с производительностью.

...