Εξαίρεση Χειρισμός σε Oracle PL/SQL (Παραδείγματα)
⚡ Έξυπνη Σύνοψη
Εξαίρεση χειρισμός σε Oracle Το PL/SQL καταγράφει σφάλματα χρόνου εκτέλεσης που εμποδίζουν την εκτέλεση ενός μπλοκ, επιτρέποντας στη μηχανή να μεταφέρει τον έλεγχο σε μια ενότητα ΕΞΑΙΡΕΣΗΣ όπου οι προκαθορισμένοι, οι οριζόμενοι από τον χρήστη και οι χειριστές ΑΛΛΩΝ απαντούν, δημιουργούν ή διαδίδουν σφάλματα με ασφάλεια.

Τι είναι ο χειρισμός εξαιρέσεων στο PL/SQL;
Μια εξαίρεση προκύπτει όταν η μηχανή PL/SQL συναντά μια εντολή που δεν μπορεί να εκτελέσει λόγω ενός σφάλματος που προκύπτει κατά τον χρόνο εκτέλεσης. Αυτά τα σφάλματα δεν ανιχνεύονται κατά τον χρόνο μεταγλώττισης και επομένως πρέπει να αντιμετωπίζονται μόνο κατά τον χρόνο εκτέλεσης.
Για παράδειγμα, εάν η μηχανή PL/SQL λάβει μια εντολή να διαιρέσει έναν αριθμό με το μηδέν, εμφανίζει το σφάλμα ως εξαίρεση. Η εξαίρεση εμφανίζεται μόνο κατά τον χρόνο εκτέλεσης από τη μηχανή PL/SQL.
Μια εξαίρεση εμποδίζει το πρόγραμμα να εκτελεστεί περαιτέρω, επομένως για να αποφευχθεί μια τέτοια κατάσταση, το σφάλμα πρέπει να καταγραφεί και να αντιμετωπιστεί ξεχωριστά. Αυτή η διαδικασία ονομάζεται χειρισμός εξαιρέσεων, κατά την οποία ο προγραμματιστής χειρίζεται το σφάλμα που μπορεί να προκύψει κατά τον χρόνο εκτέλεσης.
Εξαίρεση-Χειρισμός Σύνταξη
Οι εξαιρέσεις αντιμετωπίζονται σε επίπεδο μπλοκ. Μόλις παρουσιαστεί μια εξαίρεση σε ένα μπλοκ, ο έλεγχος εγκαταλείπει το τμήμα εκτέλεσης αυτού του μπλοκ και η εξαίρεση αντιμετωπίζεται στη συνέχεια στο τμήμα χειρισμού εξαιρέσεων του μπλοκ. Μετά τον χειρισμό της εξαίρεσης, ο έλεγχος δεν μπορεί να επιστρέψει στην ενότητα εκτέλεσης του ίδιου μπλοκ.
Η παρακάτω εικόνα δείχνει πώς η ενότητα εκτέλεσης και η ενότητα χειρισμού εξαιρέσεων βρίσκονται μέσα σε ένα μόνο μπλοκ PL/SQL:
Η παρακάτω σύνταξη εξηγεί πώς να εντοπίσετε και να διαχειριστείτε μια εξαίρεση.
BEGIN <execution block> . . EXCEPTION WHEN <exceptionl_name> THEN <Exception handling code for the “exception 1 _name’' > WHEN OTHERS THEN <Default exception handling code for all exceptions > END;
Επεξήγηση σύνταξης:
- Στην παραπάνω σύνταξη, το μπλοκ χειρισμού εξαιρέσεων περιέχει μια σειρά από συνθήκες WHEN για τον χειρισμό εξαιρέσεων.
- Κάθε συνθήκη WHEN ακολουθείται από ένα όνομα εξαίρεσης που αναμένεται να ενεργοποιηθεί κατά τον χρόνο εκτέλεσης.
- Όταν εμφανίζεται μια εξαίρεση κατά τον χρόνο εκτέλεσης, η μηχανή PL/SQL αναζητά στο τμήμα χειρισμού εξαιρέσεων τη συγκεκριμένη εξαίρεση, ξεκινώντας από την πρώτη ρήτρα WHEN και κινούμενη διαδοχικά.
- Εάν βρει έναν χειριστή για την εξαίρεση που προέκυψε, εκτελεί αυτόν τον συγκεκριμένο κώδικα χειριστή.
- Εάν δεν υπάρχει όρος WHEN που να ταιριάζει με την εξαίρεση που έχει προκύψει, η μηχανή PL/SQL εκτελεί το μέρος WHEN OTHERS, εάν υπάρχει. Αυτός ο χειριστής είναι κοινός σε όλες τις εξαιρέσεις.
- Αφού εκτελεστεί ο χειριστής, ο έλεγχος εγκαταλείπει το τρέχον μπλοκ.
- Μόνο ένας χειριστής εξαιρέσεων μπορεί να εκτελεστεί για ένα μπλοκ κατά το χρόνο εκτέλεσης. Μετά την εκτέλεση, η μηχανή παρακάμπτει τους υπόλοιπους χειριστές και εγκαταλείπει το τρέχον μπλοκ.
Σημείωση: Η συνάρτηση WHEN OTHERS θα πρέπει πάντα να τοποθετείται τελευταία στην ακολουθία. Οποιοσδήποτε χειριστής γράφεται μετά την συνάρτηση WHEN OTHERS δεν εκτελείται ποτέ, επειδή ο έλεγχος τερματίζεται από το μπλοκ μόλις εκτελεστεί η συνάρτηση WHEN OTHERS.
Τύποι Εξαίρεσης
Υπάρχουν δύο είδη εξαιρέσεων στο PL / SQL.
- Προκαθορισμένες εξαιρέσεις
- Εξαιρέσεις που καθορίζονται από τον χρήστη
Προκαθορισμένες Εξαιρέσεις
Oracle έχει προκαθορίσει ορισμένες συνηθισμένες εξαιρέσεις. Κάθε προκαθορισμένη εξαίρεση έχει ένα μοναδικό όνομα και αριθμό σφάλματος και όλες δηλώνονται στο πακέτο STANDARD στο OracleΣτον κώδικα, μπορείτε να χρησιμοποιήσετε αυτά τα προκαθορισμένα ονόματα εξαιρέσεων απευθείας για να χειριστείτε τα αντίστοιχα σφάλματα. Πολλά από αυτά αντιστοιχίζονται απευθείας σε κοινά σφάλματα. SQL λάθη που συναντάς καθημερινά.
Παρακάτω παρατίθενται μερικές προκαθορισμένες εξαιρέσεις:
| Εξαίρεση | Λάθος Code | Λόγος εξαίρεσης |
|---|---|---|
| ACCESS_INTO_NULL | ORA-06530 | Ανάθεση τιμής στα χαρακτηριστικά ενός μη αρχικοποιημένου αντικειμένου |
| ΠΕΡΙΠΤΩΣΗ_ΔΕΝ_ΒΡΕΘΗΚΕ | ORA-06592 | Καμία από τις ρήτρες WHEN σε μια πρόταση CASE δεν ικανοποιείται και καμία ρήτρα ELSE δεν καθορίζεται |
| COLLECTION_IS_NULL | ORA-06531 | Χρήση μεθόδων συλλογής (εκτός από την EXISTS) ή πρόσβαση σε χαρακτηριστικά συλλογής σε μια μη αρχικοποιημένη συλλογή |
| CURSOR_ALREADY_OPEN | ORA-06511 | Προσπαθώντας να ανοίξετε ένα δρομέας που είναι ήδη ανοιχτό |
| DUP_VAL_ON_INDEX | ORA-00001 | Αποθήκευση διπλότυπης τιμής σε μια στήλη βάσης δεδομένων που περιορίζεται από ένα μοναδικό ευρετήριο |
| INVALID_CURSOR | ORA-01001 | Παράνομες λειτουργίες κέρσορα, όπως το κλείσιμο ενός κλειστού κέρσορα |
| INVALID_NUMBER | ORA-01722 | Η μετατροπή ενός χαρακτήρα σε αριθμό απέτυχε λόγω μη έγκυρου αριθμητικού χαρακτήρα |
| ΔΕ ΒΡΕΘΗΚΑΝ ΔΕΔΟΜΕΝΑ | ORA-01403 | Μια πρόταση SELECT που περιέχει έναν όρο INTO δεν ανακτά γραμμές |
| ROW_MISMATCH | ORA-06504 | Ο τύπος δεδομένων μεταβλητής δρομέα δεν είναι συμβατός με τον πραγματικό τύπο επιστροφής δρομέα |
| SUBSCRIPT_BEYOND_COUNT | ORA-06533 | Αναφορά σε μια συλλογή με αριθμό ευρετηρίου μεγαλύτερο από το μέγεθος της συλλογής |
| SUBSCRIPT_OUTSIDE_LIMIT | ORA-06532 | Αναφορά σε μια συλλογή με έναν αριθμό ευρετηρίου εκτός του νόμιμου εύρους (για παράδειγμα, -1) |
| TOO_MANY_ROWS | ORA-01422 | Μια πρόταση SELECT με έναν όρο INTO επιστρέφει περισσότερες από μία γραμμές |
| VALUE_ERROR | ORA-06502 | Ένα αριθμητικό σφάλμα ή σφάλμα περιορισμού μεγέθους (για παράδειγμα, ανάθεση τιμής μεγαλύτερης από το μέγεθος της μεταβλητής) |
| ZERO_DIVIDE | ORA-01476 | Διαίρεση ενός αριθμού με το μηδέν |
Εξαίρεση που καθορίζεται από το χρήστη
Εκτός από τις προκαθορισμένες εξαιρέσεις που αναφέρονται παραπάνω, ένας προγραμματιστής μπορεί να δημιουργήσει προσαρμοσμένες εξαιρέσεις και να τις χειριστεί. Δημιουργούνται σε επίπεδο υποπρογράμματος στο τμήμα δήλωσης και είναι ορατές μόνο μέσα σε αυτό το υποπρόγραμμα. Μια εξαίρεση που ορίζεται σε μια προδιαγραφή πακέτου είναι μια δημόσια εξαίρεση και είναι ορατή οπουδήποτε είναι δυνατή η πρόσβαση στο πακέτο.
Σύνταξη: Σε επίπεδο υποπρογράμματος
DECLARE <exception_name> EXCEPTION; BEGIN <Execution block> EXCEPTION WHEN <exception_name> THEN <Handler> END;
- Στην παραπάνω σύνταξη, η μεταβλητή 'exception_name' ορίζεται ως ο τύπος EXCEPTION.
- Στη συνέχεια, μπορεί να χρησιμοποιηθεί με τον ίδιο τρόπο όπως μια προκαθορισμένη εξαίρεση.
Σύνταξη: Σε επίπεδο προδιαγραφών πακέτου
CREATE PACKAGE <package_name> IS <exception_name> EXCEPTION; . . END <package_name>;
- Στην παραπάνω σύνταξη, η μεταβλητή 'exception_name' ορίζεται ως ο τύπος ΕΞΑΙΡΕΣΗΣ στην προδιαγραφή πακέτου του .
- Μπορεί να χρησιμοποιηθεί σε όλη τη βάση δεδομένων όπου μπορεί να κληθεί το πακέτο 'package_name'.
Εξαίρεση αύξησης PL/SQL
Όλες οι προκαθορισμένες εξαιρέσεις ενεργοποιούνται έμμεσα κάθε φορά που παρουσιάζεται το αντίστοιχο σφάλμα. Ωστόσο, οι εξαιρέσεις που ορίζονται από τον χρήστη πρέπει να ενεργοποιούνται ρητά χρησιμοποιώντας τη λέξη-κλειδί RAISE. Η RAISE μπορεί να χρησιμοποιηθεί με τους τρόπους που φαίνονται παρακάτω.
Εάν η συνάρτηση RAISE χρησιμοποιηθεί μόνη της μέσα σε έναν χειριστή, διαδίδει την ήδη ενεργοποιημένη εξαίρεση στο γονικό μπλοκ. Μπορεί να χρησιμοποιηθεί μόνο μέσα σε ένα μπλοκ εξαιρέσεων, όπως φαίνεται παρακάτω.
Το παρακάτω στιγμιότυπο οθόνης δείχνει τη χρήση της RAISE μόνο του για την εκ νέου δημιουργία μιας εξαίρεσης στο περικλείον μπλοκ:
CREATE [ PROCEDURE | FUNCTION ] AS BEGIN <Execution block> EXCEPTION WHEN <exception_name> THEN <Handler> RAISE; END;
Επεξήγηση σύνταξης:
- Στην παραπάνω σύνταξη, η λέξη-κλειδί RAISE χρησιμοποιείται μέσα στο μπλοκ χειρισμού εξαιρέσεων.
- Κάθε φορά που το πρόγραμμα συναντά την εξαίρεση 'exception_name', η εξαίρεση αντιμετωπίζεται και ολοκληρώνεται κανονικά.
- Η λέξη-κλειδί RAISE στον χειριστή στη συνέχεια μεταδίδει την ίδια εξαίρεση στο γονικό πρόγραμμα.
Σημείωση: Όταν δημιουργείται μια εξαίρεση στο γονικό μπλοκ, η εξαίρεση που δημιουργείται πρέπει επίσης να είναι ορατή στο γονικό μπλοκ. Διαφορετικά Oracle κάνει λάθος.
Μπορείτε επίσης να χρησιμοποιήσετε τη λέξη-κλειδί RAISE ακολουθούμενη από ένα όνομα εξαίρεσης για να ενεργοποιήσετε αυτήν τη συγκεκριμένη εξαίρεση που ορίζεται από τον χρήστη ή προκαθορίζεται. Αυτή η φόρμα μπορεί να χρησιμοποιηθεί τόσο στο τμήμα εκτέλεσης όσο και στο τμήμα χειρισμού εξαιρέσεων.
Το παρακάτω στιγμιότυπο οθόνης δείχνει το RAISE ακολουθούμενο από ένα όνομα εξαίρεσης για την ενεργοποίηση μιας συγκεκριμένης εξαίρεσης:
CREATE [ PROCEDURE | FUNCTION ] AS BEGIN <Execution block> RAISE <exception_name> EXCEPTION WHEN <exception_name> THEN <Handler> END;
Επεξήγηση σύνταξης:
- Στην παραπάνω σύνταξη, η λέξη-κλειδί RAISE χρησιμοποιείται στο τμήμα εκτέλεσης, ακολουθούμενη από την εξαίρεση 'exception_name'.
- Αυτό προκαλεί αυτήν τη συγκεκριμένη εξαίρεση κατά το χρόνο εκτέλεσης και στη συνέχεια πρέπει να αντιμετωπιστεί ή να ενεργοποιηθεί περαιτέρω.
Παράδειγμα 1: Σε αυτό το παράδειγμα, θα δούμε:
- Πώς να δηλώσετε μια εξαίρεση
- Πώς να ενεργοποιήσετε την δηλωμένη εξαίρεση
- Πώς να το διαδώσετε στο κύριο μπλοκ
Το παρακάτω στιγμιότυπο οθόνης δείχνει ολόκληρο το μπλοκ που δηλώνει το sample_exception, το ανεβάζει μέσα σε ένα ένθετο μπλοκ και το μεταδίδει στο κύριο μπλοκ:
Το ακόλουθο στιγμιότυπο οθόνης δείχνει τη συνέχεια του ίδιου παραδείγματος, όπου το κύριο μπλοκ καταγράφει τελικά την εξαγόμενη εξαίρεση:
DECLARE Sample_exception EXCEPTION; PROCEDURE nested_block IS BEGIN Dbms_output.put_line('Inside nested block'); Dbms_output.put_line('Raising sample_exception from nested block'); RAISE sample_exception; EXCEPTION WHEN sample_exception THEN Dbms_output.put_line ('Exception captured in nested block. Raising to main block'); RAISE; END; BEGIN Dbms_output.put_line('Inside main block'); Dbms_output.put_line('Calling nested block'); Nested_block; EXCEPTION WHEN sample_exception THEN Dbms_output.put_line ('Exception captured in main block'); END; /
Code Επεξήγηση:
- Code γραμμή 2: Δήλωση της μεταβλητής 'sample_exception' ως τύπου ΕΞΑΙΡΕΣΗΣ.
- Code γραμμή 3: Δήλωση της διαδικασίας nested_block.
- Code γραμμή 6: Εκτύπωση της πρότασης «Μέσα σε ένθετο μπλοκ».
- Code γραμμή 7: Εκτύπωση της πρότασης "Raising sample_exception from nested block".
- Code γραμμή 8: Αύξηση της εξαίρεσης χρησιμοποιώντας το 'RAISE sample_exception'.
- Code γραμμή 10: Χειριστής εξαιρέσεων για την εξαίρεση sample_exception στο ένθετο μπλοκ.
- Code γραμμή 11: Εκτύπωση της πρότασης "Η εξαίρεση καταγράφηκε στο ένθετο μπλοκ. Ανύψωση στο κύριο μπλοκ".
- Code γραμμή 12: Ανύψωση της εξαίρεσης στο κύριο μπλοκ (διάδοσή της).
- Code γραμμή 15: Εκτύπωση της δήλωσης «Μέσα στο κύριο μπλοκ».
- Code γραμμή 16: Εκτύπωση της δήλωσης «Κλήση ένθετου μπλοκ».
- Code γραμμή 17: Κλήση της διαδικασίας nested_block.
- Code γραμμή 19: Πρόγραμμα χειρισμού εξαίρεσης για sample_exception στο κύριο μπλοκ.
- Code γραμμή 20: Εκτύπωση της δήλωσης "Η εξαίρεση καταγράφηκε στο κύριο μπλοκ".
Σημαντικά σημεία που πρέπει να σημειωθούν στην Εξαίρεση
- Σε μια συνάρτηση, μια εξαίρεση θα πρέπει πάντα είτε να επιστρέφει μια τιμή είτε να αυξάνει περαιτέρω την εξαίρεση. Διαφορετικά Oracle Εμφανίζει το σφάλμα 'Η συνάρτηση επιστράφηκε χωρίς τιμή' κατά τον χρόνο εκτέλεσης.
- Δηλώσεις ελέγχου συναλλαγών μπορούν να εκδοθούν μέσα στο μπλοκ χειρισμού εξαιρέσεων.
- Οι SQLERRM και SQLCODE είναι ενσωματωμένες συναρτήσεις που επιστρέφουν το μήνυμα εξαίρεσης και τον κώδικα εξαίρεσης αντίστοιχα.
- Εάν μια εξαίρεση δεν αντιμετωπιστεί, τότε από προεπιλογή όλες οι ενεργές συναλλαγές σε αυτήν την περίοδο λειτουργίας ακυρώνονται.
- ΣΦΑΛΜΑ_ΑΝΕΛΙΞΗΣ_ΕΦΑΡΜΟΓΗΣ (-) , ) μπορεί να χρησιμοποιηθεί αντί για RAISE για την εμφάνιση σφάλματος με έναν προσαρμοσμένο κωδικό και μήνυμα. Ο κωδικός σφάλματος πρέπει να είναι μεταξύ -20000 και -20999.





