Le procedure memorizzate CLR sono preferite rispetto alle procedure memorizzate TSQL in SQL 2005+?

StackOverflow https://stackoverflow.com/questions/58190

  •  09-06-2019
  •  | 
  •  

Domanda

La mia opinione attuale è no, preferisco le procedure memorizzate Transact SQL perché sono un'opzione più leggera e (possibilmente) con prestazioni più elevate, mentre le procedure CLR consentono agli sviluppatori di compiere ogni tipo di danno.

Tuttavia recentemente ho avuto bisogno di eseguire il debug di alcuni processi memorizzati TSQL scritti molto male.Come al solito ho riscontrato molti problemi dovuti al fatto che lo sviluppatore originale non aveva una vera esperienza TSQL, erano focalizzati su ASP.NET/C#.

Pertanto, l'utilizzo delle procedure CLR fornirebbe in primo luogo un set di strumenti molto più familiare a questo tipo di sviluppatore e, in secondo luogo, le funzionalità di debug e test sarebbero più potenti (ad esempio Visual Studio anziché SQL Management Studio).

Sarei molto interessato a conoscere la tua esperienza perché sembra che non sia una scelta semplice.

È stato utile?

Soluzione

Ci sono posti sia per T-SQL che per CLR ben scritti e ben congegnati.Se alcune funzioni non vengono chiamate frequentemente e se richiedono procedure estese in SQL Server 2000, CLR potrebbe essere un'opzione.Anche eseguire operazioni come i calcoli proprio accanto ai dati può essere interessante.Ma risolvere i cattivi programmatori introducendo nuove tecnologie sembra una cattiva idea.

Altri suggerimenti

Le procedure archiviate CLR non sono destinate a sostituire le query basate su set.Se devi eseguire una query sul database, dovrai comunque inserire SQL nel codice CLR, proprio come se fosse incorporato nel codice normale.Questo sarebbe uno spreco di sforzi.

Le procedure memorizzate CLR servono a due cose principali:1) interazione con il sistema operativo, come leggere da un file o rilasciare un messaggio in MSMQ, e 2) eseguire calcoli complessi, soprattutto quando si dispone già del codice scritto in un linguaggio .NET per eseguire il calcolo.

L'hosting di CLR all'interno di SQL Server ha lo scopo di fornire agli sviluppatori di database opzioni più flessibili nel modo in cui cercavano di portare a termine i compiti.Come altri hanno già detto, SQL è ottimo per operazioni e modifiche insiemi di dati.Chiunque abbia sviluppato estensivamente applicazioni di grandi dimensioni con regole aziendali/di dominio complesse probabilmente te lo direbbe: provare a applicare alcune di queste regole utilizzando SQL puro (a volte in una singola query macro) può diventare davvero da incubo.

Ci sono solo alcune attività che è meglio gestire in modo procedurale o OO.Avendo la possibilità di utilizzare il codice .NET per suddividere la sequenza logica, le operazioni di query possono diventare più facili da leggere ed eseguire il debug.Avendo utilizzato i processi memorizzati CLR, posso dirti che procedere con il debugger rende davvero più semplice seguire ciò che sta accadendo a livello di database.

Solo un esempio: qui utilizziamo spesso le procedure archiviate CLR come "gateway" per le query di ricerca dinamiche.Supponiamo che una richiesta di ricerca possa avere fino a 30 parametri di ricerca diversi.Gli utenti ovviamente non li utilizzano tutti e 30, quindi la struttura dati passata avrà 30 parametri ma principalmente DBNULL.Il lato client ha nessuna opzione per generare un'istruzione dinamica, per ovvi motivi di sicurezza.L'affermazione dinamica risultante viene generata internamente senza timore di "extra" esterni.

In generale usi CLR se hai qualcosa che non ha bisogno di interfacciarsi molto con il database.Quindi diciamo che stai analizzando o decodificando un valore.Questa operazione è più semplice da eseguire nel CLR e quindi restituire il valore.

Cercare di eseguire una query complessa nel CLR non è la strada da percorrere.

A proposito, questo non è cambiato neanche nel 2008.

Credo che i due non siano equivalenti...adatti a confrontarsi l'uno con l'altro.
Si suppone che l'integrazione CLR elimini gradualmente le "procedure archiviate estese" di un tempo. Ne abbiamo alcuni sul posto di lavoro...essenzialmente blocchi di elaborazione/logica su dati SQL che erano troppo difficili/impossibili da eseguire tramite le procedure memorizzate DB convenzionali/T SQL.Quindi l'hanno scritto come procedure memorizzate estese nelle DLL C++ che possono essere richiamate in modo simile.Ora sono stati gradualmente eliminati e l'integrazione CLR ne è la sostituzione

  • Procedure memorizzate DB:se può essere fatto nei processi T SQL Stored, fallo.
  • Procedure archiviate CLR:se la logica è troppo complessa o noiosa da eseguire tramite T SQL...se è qualcosa che richiederà meno righe di codice CLR per affrontarlo (manipolazione di stringhe, ordinamento o filtraggio complesso/personalizzato, ecc.), utilizzare questo approccio.

A parte l'accesso al file system (dove i processi CLR hanno un vantaggio molto pronunciato), utilizzerei i processi T-SQL.Se hai calcoli particolarmente complessi potresti inserire quel pezzo in un CLR funzione e chiamalo dal tuo processo (udf è dove ho scoperto che l'integrazione CLR brilla davvero).Quindi ottieni i vantaggi dell'integrazione CLR per quella particolare parte della tua attività, ma mantieni la maggior parte possibile della logica di proc archiviata nel DB.

Considerato quello che hai detto, preferirei che gli sviluppatori fossero adeguatamente formati su t-SQl e sui database in generale piuttosto che consentire loro di creare forse molti più danni alle prestazioni consentendo loro di svolgere attività t-sql nei CLR.Gli sviluppatori che non capiscono i database lo usano come scusa per evitare di fare le cose nel modo migliore per le prestazioni del database perché vogliono prendere quella che vedono come la strada più semplice.

Dipende sempre dallo strumento giusto per il lavoro, quindi dipende davvero da ciò che stai cercando di realizzare.

Tuttavia, come regola generale, hai ragione nel dire che i processi CLR hanno un sovraccarico maggiore e non eseguiranno mai operazioni preimpostate come T-SQL.La mia linea guida è fare tutto in T-SQL a meno che ciò di cui hai bisogno non diventi eccessivamente complicato in T-SQL.Quindi, sforzati di far funzionare l'approccio T-SQL.:-)

I processi CLR sono fantastici e hanno il loro posto, ma il loro utilizzo dovrebbe essere l'eccezione, non la regola.

La documentazione in linea di SQL Server pagina sull'argomento elenca questi vantaggi:

  • Un modello di programmazione migliore. I linguaggi .NET Framework sono per molti aspetti più ricchi di Transact-SQL, poiché offrono costrutti e funzionalità precedentemente non disponibili agli sviluppatori di SQL Server.Gli sviluppatori possono anche sfruttare la potenza della libreria .NET Framework, che fornisce un ampio set di classi che possono essere utilizzate per risolvere in modo rapido ed efficiente i problemi di programmazione.

  • Maggiore sicurezza e protezione. Il codice gestito viene eseguito in un ambiente runtime del linguaggio comune, ospitato dal Motore di database.SQL Server sfrutta questa funzionalità per fornire un'alternativa più sicura alle stored procedure estese disponibili nelle versioni precedenti di SQL Server.

  • Capacità di definire tipi di dati e funzioni aggregate. I tipi definiti dall'utente e gli aggregati definiti dall'utente sono due nuovi oggetti di database gestiti che espandono le funzionalità di archiviazione ed esecuzione di query di SQL Server.

  • Sviluppo semplificato attraverso un ambiente standardizzato. Lo sviluppo del database è integrato nelle versioni future dell'ambiente di sviluppo Microsoft Visual Studio .NET.Per lo sviluppo e il debug di oggetti di database e script, gli sviluppatori utilizzano gli stessi strumenti utilizzati per scrivere componenti e servizi .NET Framework di livello intermedio o client.

  • Potenziale per prestazioni e scalabilità migliorate. In molte situazioni, i modelli di compilazione ed esecuzione del linguaggio .NET Framework offrono prestazioni migliorate rispetto a Transact-SQL.

Ci siamo imbattuti in una situazione con una funzione CLR che è stata chiamata migliaia di volte in una normale procedura SQL.Si trattava di una procedura per importare dati da un altro sistema.La funzione ha convalidato i dati e ha gestito bene i valori nulli.

Se abbiamo eseguito l'operazione in TSQL, l'elaborazione è terminata in circa 15 secondi.Se utilizzassimo la funzione CLR, la procedura terminava in 20-40 minuti.La funzione CLR sembrava più elegante, ma per quanto abbiamo potuto vedere, si verificava un successo all'avvio per ogni utilizzo della funzione CLR.Pertanto, se si esegue un'operazione di grandi dimensioni utilizzando una funzione CLR, va bene poiché il tempo di avvio è ridotto rispetto al tempo dell'operazione.Oppure, se chiami la funzione CLR un numero modesto di volte, il tempo di avvio totale per tutte le invocazioni della funzione sarebbe piccolo.Ma attenzione ai loop.

Inoltre, per motivi di manutenibilità, è meglio non avere più lingue di quelle realmente necessarie.

Vorrei aggiungere un paio di motivi per utilizzare CLR che potrebbero non essere stati menzionati.

  • Sostituisci ed estendi le funzioni SQL di base, non query e scalari.
    R) La segnalazione degli errori e gli avvisi possono essere integrati in base ai requisiti definiti.B) Definire facilmente i livelli di debug.C) Abilitare un modo più semplice per interagire con server SQL esterni
  • Sposta il codice legacy in un ambiente gestito.

Ho postato la seguente risposta ad una domanda simile: Vantaggio di SQL SERVER CLR.Aggiungerò qui, però, che C# / VB.net / etc è un linguaggio con cui qualcuno si sente più a suo agio di quanto dovrebbe fare T-SQL non essere un motivo per utilizzare SQLCLR su T-SQL.Se qualcuno non sa come realizzare qualcosa in T-SQL, chiedi prima aiuto per trovare una soluzione T-SQL.Se uno non esiste, Poi seguire il percorso CLR.


L'integrazione SQLCLR/CLR all'interno di SQL Server è solo un altro strumento per risolvere alcuni problemi (non tutti).Ci sono alcune cose che fa meglio di quanto può essere fatto in T-SQL puro e ci sono alcune cose che possono essere fatte solo tramite SQLCLR.Ho scritto un articolo per SQL Server Central, Scala per SQLCLR Livello 1:Cos'è SQLCLR? (per leggere gli articoli è necessaria la registrazione gratuita), che affronta questa domanda.Le basi sono (vedi l'articolo collegato per i dettagli):

  • Streaming di funzioni con valori di tabella (sTVF)
  • SQL dinamico (all'interno di Funzioni)
  • Migliore accesso alle risorse esterne / Sostituisci xp_cmdshell
    • Passare i dati è più semplice
    • Ottenere più colonne di un risultato arretrato è più semplice
    • Nessuna dipendenza esterna (es.7zip.exe)
    • Maggiore sicurezza tramite la rappresentazione
  • Capacità di multi-thread
  • Gestione degli errori (all'interno delle funzioni)
  • Aggregati personalizzati
  • Tipi personalizzati
  • Modifica stato (all'interno di una funzione e senza OPENQUERY / OPENROWSET)
  • Esegui una procedura memorizzata (sola lettura;all'interno di una funzione e senza OPENQUERY / OPENROWSET)
  • Prestazione (Nota: questo è non significato in tutti i casi, ma sicuramente in alcuni casi a seconda del tipo e della complessità dell'operazione)
  • Può acquisire l'output (ad es.cosa viene inviato alla scheda Messaggi in SSMS) (ad es. PRINT E RAISERROR con un gravità = da 0 a 10) -- Ho dimenticato di menzionarlo nell'articolo ;-).

Un'altra cosa da considerare è che a volte è vantaggioso poter condividere il codice tra l'app e il DB in modo che il DB abbia informazioni dettagliate su determinate logiche aziendali senza dover creare schermate personalizzate solo interne solo per accedere al codice dell'app.Ad esempio, ho lavorato su un sistema che importava file di dati dai clienti e utilizzava un hash personalizzato della maggior parte dei campi e salvava quel valore nella riga nel DB.Ciò consentiva di saltare facilmente le righe quando si importavano nuovamente i dati poiché l'app eseguiva l'hashing dei valori dal file di input e li confrontava con il valore hash memorizzato sulla riga.Se fossero stati gli stessi, allora avremmo capito subito che nessuno dei campi era cambiato, quindi saremmo passati alla riga successiva, ed era un semplice confronto INT.Ma quell'algoritmo per eseguire l'hash era solo nel codice dell'app, quindi sia per eseguire il debug di un caso cliente o per cercare modi per scaricare parte dell'elaborazione sui servizi back-end contrassegnando le righe che avevano almeno un campo con modifiche (modifiche provenienti dalla nostra app invece di cercare modifiche all'interno di un file di importazione più recente), non potevo fare nulla.Sarebbe stata una grande opportunità avere un po' di logica aziendale piuttosto semplice nel DB, anche se non per la normale elaborazione;avere ciò che equivale a un valore codificato nel DB senza la capacità di comprenderne il significato rende molto difficile risolvere i problemi.

Se sei interessato a vedere alcune di queste funzionalità in azione senza dover scrivere alcun codice, la versione gratuita di SQL# (di cui sono l'autore) ha funzioni RegEx, aggregati personalizzati (UDA), tipi personalizzati (UDT), ecc.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top