Вызов динамического 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
Ответы
Ответ 1
Вы не можете использовать динамический sql в udf:
Это очень просто: вы не можете использовать динамический SQL из заданного функции, написанные в T-SQL. Это потому, что вам не разрешено делать что-либо в UDF, который может изменить состояние базы данных (поскольку UDF может вызывается как часть запроса). Поскольку вы можете делать что угодно из динамического SQL, включая обновления, очевидно, почему динамический SQL не допускается.
...
В SQL 2005 и более поздних версиях вы можете реализовать свою функцию как CLR функция. Напомним, что весь доступ к данным из CLR является динамическим SQL. (Вы надежно защищены, так что если вы выполняете операцию обновления с ваша функция, вас поймают.) Слово предупреждения, хотя: данные доступ со скалярных UDF может часто приводить к проблемам с производительностью.