2012-03-07 22 views
14

Sto scrivendo una funzione che restituisce una tabella. Ci sono due parametri che vengono passati alla funzione e una query viene creata ed eseguita e inserita nella tabella di ritorno. Tuttavia sto ricevendo questo errore.Chiama SQL dinamico dalla funzione

Solo funzioni e alcune stored procedure estese possono essere eseguite da una funzione.

Vorrei non utilizzare una stored procedure in quanto si tratta di una semplice funzione di utilità. Qualcuno sa se questo può essere fatto. La mia funzione è codificata di seguito, controlla i duplicati per una determinata colonna all'interno di una certa tabella.

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

risposta

21

You can't use dynamic sql in a udf:

Questo molto semplice: non è possibile utilizzare SQL dinamico a partire da Usato-definiti funzioni scritte in T-SQL. Ciò è dovuto al fatto che non è consentito eseguire in una UDF che potrebbe modificare lo stato del database (poiché l'UDF può essere invocato come parte di una query come ). Poiché è possibile eseguire qualsiasi operazione da SQL dinamico , inclusi gli aggiornamenti, è ovvio il motivo per cui SQL dinamico non è consentito.

...

In SQL 2005 e versioni successive, è possibile implementare la funzione come una funzione CLR . Ricorda che tutti gli accessi ai dati da CLR sono SQL dinamici. (Sei protetto, così se esegui un'operazione di aggiornamento da alla tua funzione, verrai catturato.) Una parola di avvertimento però: l'accesso ai dati dalle UDF scalari può spesso dare problemi di prestazioni.

+0

Come posso rendere questa una funzione CLR? – JBone

+0

[Procedura: creare ed eseguire una funzione definita dall'utente di SQL Server CLR] (http://msdn.microsoft.com/en-us/library/w2kae45k (v = vs.80) .aspx) –

+1

'Poiché è possibile fare qualsiasi cosa dall'SQL dinamico, inclusi gli aggiornamenti, è ovvio il motivo per cui SQL dinamico non è permesso. ', questo è corretto. Ma allo stesso tempo devi analizzare il tuo sql dinamico con es. sp_executesql(), quindi SQL Server ha tutte le possibilità per catturare i dati che cambiano query e lasciare che altri passino. Quindi è la vera ragione: non si sono preoccupati di implementarlo? –

Problemi correlati