Implementarea gestionării excepțiilor structurate
Acum, că aveți o înțelegere a naturii erorilor și a gestionării de bază a erorilor în T-SQL, este momentul să priviți o formă mai complexă de tratare a erorilor. Gestionarea excepțiilor structurate a fost introdusă în SQL Server 2005.
Aici veți vedea cum să-l utilizați și să-i evaluați avantajele și limitările, inclusiv blocul TRY CATCH, rolul funcțiilor de tratare a erorilor și înțelegerea diferenței dintre erorile care pot fi recuperate și cele care nu se pot utiliza. În sfârșit, veți vedea cum pot fi gestionate și surfaced erorile atunci când este necesar.
Ce este programarea blocului TRY/CATCH
Gestionarea excepțiilor structurate este mai puternică decât gestionarea erorilor pe baza variabilei de sistem @@ERROR. Acesta vă permite să împiedicați gunoiul de cod cu cod de tratare a erorilor și să centralizați acel cod de tratare a erorilor. Centralizarea codului de tratare a erorilor înseamnă, de asemenea, că vă puteți concentra mai mult asupra scopului codului, nu asupra gestionării erorilor pe care le conține.
Blocul TRY și blocul CATCH
Atunci când utilizați gestionarea excepțiilor structurate, codul care poate ridica o eroare este plasat într-un bloc TRY. Blocurile TRY sunt încadrate de instrucțiuni BEGIN TRY și END TRY .
Dacă apare o eroare capturabilă - majoritatea erorilor pot fi capturate, controlul executării se mută la blocul CATCH. Blocul CATCH este o serie de instrucțiuni T-SQL încadrate de instrucțiuni BEGIN CATCH și END CATCH .
Notă
În timp ce BEGIN CATCH și END TRY sunt instrucțiuni separate, BEGIN CATCH trebuie să urmeze imediat END TRY.
Limitări actuale
Limbile de nivel înalt oferă adesea o construcție de încercare/capturare/final și sunt utilizate adesea pentru a elibera resurse în mod implicit. Nu există niciun bloc ECHIVALENT ÎN FINAL în T-SQL.
Înțelegerea diferenței dintre erorile captabile și necatibile
Este important să vă dați seama că, deși blocurile TRY/CATCH vă permit să surprindeți o gamă mult mai largă de erori decât ați putea cu @@ERROR, nu puteți prinde fiecare tip.
Erori catchable vs. noncatchable
Nu toate erorile pot fi capturate de blocurile TRY/CATCH din același domeniu în care există blocul TRY/CATCH. Adesea, erorile care nu pot fi capturate în același domeniu pot fi capturate într-un domeniu înconjurător. De exemplu, este posibil să nu reușiți să capturați o eroare în cadrul procedurii stocate care conține blocul TRY/CATCH. Cu toate acestea, este posibil să surprindeți acea eroare într-un bloc TRY/CATCH din codul care a denumit procedura stocată în care a apărut eroarea.
Erori uzuale care nu se pot utiliza
Exemple comune de erori necatibile sunt:
- Erorile de compilare, cum ar fi erorile de sintaxă, care împiedică compilarea unui grup.
- Probleme de recompilare la nivel de instrucțiune care se referă de obicei la rezoluția de nume amânată. De exemplu, puteți crea o procedură stocată care face referire la un tabel necunoscut. S-a produs o eroare doar atunci când procedura încearcă să rezolve numele tabelului la un objectid.
Cum se regândesc erorile utilizând THROW
Dacă instrucțiunea THROW este utilizată într-un bloc CATCH fără parametri, aceasta va restabili eroarea care a determinat introducerea codului în blocul CATCH. Puteți utiliza această tehnică pentru a implementa înregistrarea în jurnal a erorilor în baza de date prin capturarea erorilor și înregistrarea în jurnal a detaliilor acestora, apoi a genera eroarea inițială la aplicația client, astfel încât să poată fi gestionată acolo.
Iată un exemplu despre cum să reintroduceți o eroare.
BEGIN TRY
-- code to be executed
END TRY
BEGIN CATCH
PRINT ERROR_MESSAGE();
THROW
END CATCH
În unele versiuni anterioare de SQL Server, nu a existat nicio metodă de a genera o eroare de sistem. Deși THROW nu poate specifica o eroare de sistem de ridicat, atunci când SE utilizează THROW fără parametri dintr-un bloc CATCH, va reraza atât erorile de sistem, cât și de utilizator.
Care sunt funcțiile de tratare a erorilor
CATCH blocks face informațiile legate de erori disponibile pe toată durata blocului CATCH. Printre acestea se numără subscopurile, cum ar fi procedurile stocate, rulate din interiorul blocului CATCH.
Funcții de tratare a erorilor
Ar trebui să rețineți că, atunci când programarea cu @@ERROR, valoarea reținută de variabila de sistem @@ERROR a fost resetată imediat ce a fost executată următoarea declarație.
Un alt avantaj esențial al tratării de excepții structurate în T-SQL este că a fost furnizată o serie de funcții de tratare a erorilor și acestea își mențin valorile în tot blocul CATCH. Funcțiile separate furnizează fiecare proprietate a unei erori care a fost ridicată.
Aceasta înseamnă că puteți scrie proceduri generice de tratare a erorilor stocate, care pot accesa în continuare informațiile referitoare la erori.
- CATCH blocks face informațiile legate de erori disponibile pe toată durata blocului CATCH.
- @@Error este resetat atunci când rulează următoarea instrucțiune.
Gestionarea erorilor în cod
Integrarea SQL CLR permite executarea codului gestionat în SQL Server. Limbile .NET de nivel înalt, cum ar fi C# și VB, au la dispoziție o gestionare detaliată a excepțiilor. Erorile pot fi prinse utilizând blocuri standard .NET try/catch/în cele din urmă.
Erori în codul gestionat
În general, este posibil să doriți să surprindeți cât mai multe erori în codul gestionat. Totuși, este important să vă dați seama că toate erorile care nu sunt tratate în codul gestionat sunt transmise înapoi la codul T-SQL apelant. De fiecare dată când orice eroare care apare în codul gestionat este returnată la SQL Server, aceasta va părea a fi o eroare 6522. Erorile pot fi imbricate și acea eroare va fi încadrată în cauza reală a erorii.
O altă cauză rară, dar posibilă a erorilor din codul gestionat ar fi faptul că codul ar putea executa o instrucțiune RAISERROR T-SQL printr-un obiect SqlCommand.