SQL dinamico e stored procedure sono due dei componenti più importanti di SQL Server. In questo articolo, esamineremo i vantaggi e gli svantaggi di ciascuno di essi e quando utilizzarli.
Prestazioni
Tutti conoscono la risposta a questa domanda. Le stored procedure battono l'SQL dinamico in termini di prestazioni. Una procedura memorizzata è memorizzata nella cache nella memoria del server e la sua esecuzione è molto più veloce dell'SQL dinamico. Se tutte le restanti variabili vengono mantenute costanti, la procedura memorizzata supera l'SQL dinamico.
Separazione delle preoccupazioni
In termini di separazione delle preoccupazioni, le stored procedure battono senza dubbio l'SQL dinamico.
Le stored procedure consentono di mantenere la logica del database separata dalla logica aziendale. Pertanto, se si verifica un errore nella logica aziendale, è sufficiente modificare il codice dell'applicazione. Al contrario, se si verifica un problema con la logica del database, è necessario modificare solo la procedura memorizzata. Inoltre, se una stored procedure viene aggiornata, non è necessario ricompilare e distribuire il codice dell'applicazione.
Se utilizzi query SQL dinamiche nel codice client, dovrai aggiornare il codice dell'applicazione se si verifica un errore nella query SQL. Ciò significa che dovrai ricompilare e distribuire il codice dell'applicazione.
Traffico di rete
Le stored procedure producono meno traffico di rete rispetto all'SQL dinamico perché l'esecuzione di una stored procedure richiede solo l'invio in rete del nome della procedura e dei parametri (se presenti).
L'esecuzione di SQL dinamico richiede l'invio della query completa attraverso la rete, aumentando il traffico di rete, in particolare se la query è molto grande.
Attacchi SQL injection
Le stored procedure non sono vulnerabili agli attacchi SQL injection.
Le query SQL dinamiche sono vulnerabili agli attacchi SQL injection se non vengono utilizzate query con parametri e le query con parametri non possono essere utilizzate con SQL dinamico se un nome di tabella o colonna viene passato come parametro.
In questo caso, la soluzione è che la funzione del nome in codice può essere utilizzata per prevenire attacchi di SQL injection.
Riutilizzabilità dei piani di query memorizzati nella cache
Le stored procedure migliorano le prestazioni del database poiché consentono il riutilizzo dei piani di query memorizzati nella cache. Nel caso dell'SQL dinamico, dovrai utilizzare query parametrizzate per aumentare la riutilizzabilità del piano di query memorizzato nella cache. In assenza di piani di query parametrizzati, SQL Server rileva automaticamente i parametri e genera piani di query memorizzati nella cache con conseguente miglioramento delle prestazioni.
È pertinente menzionare qui che solo i sistemi OLTP beneficiano della riutilizzabilità del piano di query memorizzato nella cache. Nel caso dei sistemi OLAP, la scelta dell'ottimizzatore cambia, il sistema OLAP beneficia del piano unico.
Manutenzione
Le stored procedure con SQL statico sono più facili da mantenere. Ad esempio, nel caso di SQL statico in una stored procedure, gli errori di sintassi possono essere rilevati prima dell'esecuzione. Nel caso di SQL dinamico all'interno di stored procedure, gli errori di sintassi non possono essere rilevati prima dell'esecuzione della query.
Inoltre, le procedure memorizzate sono più simili a funzioni, vengono definite una volta e quindi possono essere richiamate in qualsiasi punto dello script. Pertanto, se si desidera aggiornare una stored procedure, è necessario aggiornarla solo in un punto. Tutte le parti dell'applicazione che richiamano la stored procedure avranno accesso alla versione aggiornata. Tuttavia, uno svantaggio è che anche quelle parti dell'applicazione possono essere interessate laddove non si desidera la stored procedure aggiornata. In caso di SQL dinamico potresti dover scrivere script SQL in più punti, ma in questi casi, l'aggiornamento dello script in un punto non influisce sull'altro. La decisione tra l'utilizzo di una procedura memorizzata e SQL dinamico dipende dalla funzionalità dell'applicazione.
Sicurezza
Se più applicazioni accedono al database, è più sicuro utilizzare le stored procedure rispetto all'SQL dinamico.
Le stored procedure forniscono un ulteriore livello di sicurezza, mentre il contesto utente è l'unico modo per controllare le autorizzazioni sugli script SQL dinamici. Tutto sommato, la protezione dell'SQL dinamico è laboriosa rispetto alle procedure archiviate.
Identificazione delle dipendenze
In un database relazionale, le tabelle hanno dipendenze da altre tabelle nel database.
Considera uno scenario in cui desideri rimuovere una tabella ma, prima di farlo, vuoi scoprire tutte le dipendenze della tabella. O in parole povere, vuoi trovare le query che accedono alla tabella che vuoi eliminare. In questi casi, puoi utilizzare la stored procedure sp_depends.
Tuttavia, sp_depends può rilevare solo le dipendenze in cui viene utilizzato SQL statico all'interno di una stored procedure. Nel caso in cui l'SQL dinamico sia dipendente da una tabella, tale dipendenza non può essere rilevata dalla stored procedure sp_depends. Vediamolo in azione con l'aiuto di un semplice esempio.
Preparazione di dati fittizi
Creiamo alcuni dati fittizi per aiutare a spiegare il concetto di dipendenze in SQL statico e dinamico.
CREATE DATABASE deptest; USE deptest CREATE TABLE student ( Id int identity primary key, Name VARCHAR(50) NOT NULL, Gender VARCHAR(50) NOT NULL, Age int ) INSERT INTO student VALUES ('James', 'Male', 20), ('Helene', 'Female', 20), ('Sofia', 'Female', 20), ('Ed', 'Male', 20), ('Ron', 'Female', 20)
Ora abbiamo un database di test contenente una tabella e alcuni dati di test. Ora creiamo due stored procedure che accedono alla tabella degli studenti.
La prima procedura memorizzata utilizza SQL statico per recuperare tutti i record dalla tabella studente:
USE deptest GO CREATE PROC spStatProc AS BEGIN SELECT * FROM student END
Esegui lo script sopra. Questo script crea una procedura memorizzata "spStatProc" all'interno del database deptest.
Creiamo un'altra stored procedure che contiene SQL dinamico che recupera tutti i record dalla tabella studente.
USE deptest GO CREATE PROC spDynProc AS BEGIN DECLARE @query NVARCHAR(100) SET @query = 'SELECT * FROM student' EXECUTE sp_execute @query END
Questo script crea una procedura memorizzata "spDynProc" all'interno del database deptest. Questa procedura memorizzata utilizza un'istruzione SQL dinamica per recuperare tutti i record dalla tabella studente.
Ora abbiamo due stored procedure che hanno una dipendenza dalla tabella studente. Uno di essi contiene SQL statico e l'altro contiene SQL dinamico.
Tuttavia, se si esegue la stored procedure sp_depends e la si passa alla tabella studente come parametro, si vedrà che recupererà solo la stored procedure "spStatProc". Questo perché contiene SQL statico. La procedura memorizzata "spDynProc" verrà ignorata poiché contiene SQL dinamico.
Esegui il seguente script.
USE deptest GO EXECUTE sp_depends student
Otterrà il seguente output:
[id tabella=40 /]
Puoi vedere che sp_depends non è stato in grado di segnalare la dipendenza "spDynProc" e ha segnalato solo "spStatProc".
Complessità
Le stored procedure possono diventare estremamente complesse se si utilizza un numero elevato di filtri e sono presenti più clausole AND e OR tra i filtri. D'altra parte, utilizzando SQL dinamico è possibile generare dinamicamente clausole WHERE a seconda del tipo di filtri. Questo rende l'SQL dinamico la scelta migliore se vuoi implementare una logica estremamente complessa.
Conclusione
Nel complesso, la procedura memorizzata supera l'SQL dinamico in quasi tutti gli aspetti. Sono più veloci, sicuri e di facile manutenzione e richiedono meno traffico di rete. Come regola generale, le stored procedure dovrebbero essere utilizzate in scenari in cui non è necessario modificare le query e le query non sono molto complesse. Tuttavia, se modifichi frequentemente i nomi delle tabelle, i nomi delle colonne o il numero di parametri nella tua query, Dynamic SQL è la scelta migliore grazie alla sua strategia di implementazione più semplice.
Link utili
- SQL dinamico e stored procedure
- Non temere l'SQL dinamico
- Creazione di stored procedure ad alte prestazioni
- Classi sulle stored procedure