Eseguire Stored Procedures in una funzione UDF (SQL Server)
Un workaround per eseguire stored procedures in functions UDF con Microsoft SQL SERVER. Analizziamo la problematica e scriviamo una .NET external function che permette l’esecuzione di dynamic SQL.
Ultimamente mi sono scontrato con la problematica di eseguire una stored procedure da una funzione SQL UDF (google: How to execute Stored procedures into a UDF function).
L’esecuzione di codice INSERT/UPDATE/DELETE/STORED PROCEDURE che alterano il contesto esterno alla funzione non è possibile by design; è possibile solo apportare modifiche a variabili locali definite nella funzione. Infatti appena tentiamo di alterare il contesto del database otteniamo uno dei seguenti messaggi di errore, rispettivamente se stiamo utilizzando comandi TSQL INSERT/UPDATE/DELETE, chiamando STORED PROCEDURE o cercando di eseguire SQL dinamico:
Invalid use of side-effecting or time-dependent operator in ‘INSERT’ within a function.
Only functions and extended stored procedures can be executed from within a function.
Invalid use of side-effecting or time-dependent operator in ‘EXECUTE STRING’ within a function.
L’utilizzo delle funzioni SQL è utilizzato per leggere e applicare una certa logica ai dati letti, ma non a trasformarli o modificarli. E’difficile pensare che leggendo dei dati da una tabella con una SELECT questi vengano modificati sotto il naso.
Se ci dovessero essere logiche più complesse, come l’utilizzo di tabelle di appoggio temporanee, certo è preferibile e doveroso racchiudere il codice in una stored procedure.
Questo in linea di principio e come best practice.
Un caso che ho dovuto affrontare era quello dell’ottimizzazione delle performance di una serie di applicazioni. Queste, accedendo al DB, ed utilizzando gli strumenti offerti TSQL, utilizzavano tutte, in più punti e ripetutamente una certa funzione, che, accedendo a dati esterni al DB con protocollo TCP/IP, risultava particolarmente lenta a rispondere.
Da qui l’idea di implementare un meccanismo di caching nella funzione stessa; non era assolutamente pensabile cambiare la logica
applicativa modificando il codice e le modalità di interfacciamento al DB. L’operazione doveva essere completamente trasparente per le applicazioni!
L’algoritmo di caching può essere banalmente il seguente:
IF (prima volta) BEGIN recupera i dati online memorizzali nella cache ELSE recupera i dati dalla cache END
Includere tale logica in una funzione SQL è semplice…
Peccato che il significato di memorizzare i dati è quello di utilizzare un’istruzione del tipo INSERT/UPDATE/ST.PROCEDURE e che quindi modifica il contesto esterno alla funzione.
Nel seguito espongo la soluzione di come eseguire una stored procedure in una funzione, descrivendo i passi utili a creare una logica di caching sopra descritta.






