salve,
michele_p wrote:
...
Ho capito che sono importanti in quanto ci sono situazioni in cui si devono aggiungere/modificare/eliminare dati da un DB che per essere significativi vanno implementati con piu INSERT/UPDATE/DELETE e se non vanno a buon fine tutte si deve aver la possibilità di tornare al punto di partenza (il cosiddetto ROLLBACK). So anche che questo genere di operazioni è possibile eseguirlo con le stored procedure, che queste sono memorizzate direttamente nel db e che si scrivono in un linguaggio particolare che nel caso di SQLSERVER è il T-SQL.
Le mie domande sono:
- qualche link che illustri t-sql, i comandi gli esempi...purtroppo non ho trovato molto in merito.
- qualche esempio in cui in asp.net si fa riferimento ad una stored procedure cosi che possa farmi un idea della situazione.
per chiarirci, tutti i comandi che un applicativo client invia ad un database server sono espressi in uno dei due modi seguenti... - utilizzo di api dirette
- utilizzo di un linguaggio di alto livello, linguaggio SQL (o in uno dei suoi vari dialetti).. il database engine provvede poi ad eseguire la validazione ed il parsing dei comandi ricevuti, generazione e semplificazione dei piani di esecuzione, per poi provvedere (alla fine) alla costruzione dell'albero interno delle operazioni da eseguire, che si traducono nelle varie attivita' di recupero delle pagine di dati dalla cache ovvero fisicamente tramite operazioni di I/O..
restando in ambito SQL, quindi, tutte le operazioni richieste vanno esplicitate negli appositi comandi, siano essi DDL quindi CREATE whatever, che DML, come SELECT... INSERT.. UPDATE... DELETE...
i substrati di comunicazione ed accesso ai dati lato client, siano essi ADO, Linq, etc, possono provvedere autonomamente a generare il codice SQL relativo all'azione implementata lato client, sia esso un recordset.update (di ADO) o similare di Linq2SQL, che alla fine della fiera provvedono ad inviare al database server la finale istruzione di "UPDATE whatever SET .. WHERE ...;"
i vari modelli di accesso ai dati solitamente supportano anche l'invio di codice SQL preconfezionato dall'utente, comunemente indicato come codice SQL dinamico, alla pari del codice autogenerato dagli stessi, quindi qualche cosa come
object.execute "UPDATE whatever SET .. WHERE ...;";
che non si configura come vero e proprio codice SQL Embedded in quanto la compilazione dello stesso avviene a runtime, inviando codice SQL al database engine, che provvedera' ai passaggi di cui sopra al fine di portare a termine l'esecuzione..
tutto questo riguarda pero' una gestione lato client, nel senso che un intero batch di comandi viene "confezionato" lato client dall'applicativo o dai componenti sottostanti ed inviato come codice dinamico al server.. la maggior parte dei database engine supportano pero' la possibilita' di definire delle procedure composte da codice SQL, chiamate appunto solitamente stored procedures, dove il codice SQL da utilizzare viene archiviato nei metadati di un database.. l'applicativo client, quindi, si limitera' da inviare il comando di esecuzione della procedura interessante unitamente agli eventuali parametri ad essa necessari.. il traffico di rete quindi non includera' l'istruzione SQL da eseguire bensi' la sola chiamata alla procedura necessaria.. allo stesso modo, il database engine carichera' dai metadati del database il codice della procedura, ne eseguira' la compilazione just in time (a meno che procedure di caching interne all'engine riscontrino la presenza dell'oggetto gia' i memoria), valorizzera' i parametri interni alla procedura con quelli forniti unitamente alla chiamata, e quindi seguitera' il lavoro di esecuzione... il funzionamento risultante e' tendenzialmente simile, ma differisce nel modo e nella mentalita' di accesso ai dati e relativa protezione.. con codice SQL dinamico, si necessita solitamente giocoforza di poter direttamente accedere alle tabelle sottostanti, in quanto il codice provvisto sara' simile ad un "SELECT ... FROM whatever; / UPDATE whatever SET ...; ....", mentre l'utilizzo di stored procedures solitamente evita questa necessita', in quanto tutti gli accessi alle tabelle vengono tradotti in chiamate a stored procedures, dove il codice che le definisce puo' apporre tutte le necessarie validazioni a precludere la corruzione dei dati, e quindi ad accedere alle tabelle sottostanti.. in questo modo si negano solitamente le autorizzazioni di accesso alle tabelle e si consente la sola esecuzione di stored procedures..
in questo modo e' anche piu' semplice verificare eventuali anomalie nell'accesso ai dati, e sicuramente le applicazioni client non saranno farcite di codice SQL dinamico del quale spesso e' difficile tenere traccia.. la surface area risultante e' quindi molto piu' elegante, razionale, efficiente e funzionale (alle esigenze dei dba, che devono garantire la correttezza dei dati)..
considera ad esempio la necessita' di rintracciare "chi/cosa" abbia modificato un dato particolare... sapendo che solo le "n" procedure accedono in scrittura alla relativa tabella, risulta molto semplice ed immediato verificare le eventuali anomalie, dove invece lo scenario opposto richiede l'accesso a tutto il codice client per trovare il codice SQL da verificare ovvero tutte le istruzioni dei metodi di accesso ai dati presenti che possano risultare in codice SQL da verificare..
- Poi vorrei sapere se quello che si fa con T-SQL si possa fare anche in un linguaggio tipo C# magari non all'interno del DB ma
nell'applicazione. Chiedo questo perchè mi pare di aver capito che T-SQL non è l'unico modo in ambito .net per scrivere le stored Procedure.
a partire da SQL Server 2005, SQL Server supporta la possibilita' di scrivere stored procedures scritte in linguaggi .Net.. e' solitamente buona norma utilizzare codice Net solamente per operazioni esterne all'accesso ai dati, ad esempio funzioni con esigenze di number crunghing, operazioni su stringhe, ...
essendo le api di SQL Server fortemente basate su operazioni "set oriented", al contrario di Oracle (e altri) che molto invece di basa su cursori, e' bene utilizzarne le peculiarita'.. ovviamente nulla vieta di scrivere una stored procedure Net, che apra un cursore su una tabella da 10milioni di righe, cicli ogni riga per ritornare al chiamante la sola riga che soddisfi le esigenze proposte, ma ovviamente questo e' un uso insano degli strumenti.. come dicevo, invece, e' ottima cosa scrivere una funzione Net al fine di criptare/decriptare una stringa secondo esigenze particolari, in quanto il linguaggio SQL non e' ben improntato per affrontare queste necessita'.. si possono in qualche modo spesso eseguire, ma sicuramente .Net e' piu' efficiente e funzionale per l'esigenza..
il mio consiglio (e non solo mio) quindi, usare l'attrezzo giusto per ogni necessita'..
accesso ai dati = SQL
"cose strane" = .Net
saluti