Ако сте програмист, може да сте запознати с концепцията за обработка на изключения е неразделна част от всеки език за програмиране. Тъй като грешките са неизбежни и дори най-умните от нас могат да направят грешки, докато пишат код, трябва да сме запознати как да се справяме с тях. В тази статия ще научим по-специално за обработката на изключенията в PL/SQL.
По-долу са темите, обхванати в тази статия:
- Какво е изключение?
- Синтаксис на обработка на изключения
- Видове изключения
- Системно дефинирано
- Именувани системни изключения
- Неименувани системни изключения
- Дефинирани от потребителя
- Стъпки за деклариране на функции, дефинирани от потребителя
- Примери за дефинирани от потребителя функции
- Системно дефинирано
Какво е изключение?
Всяко необичайно състояние или събитие, което прекъсва нормалния поток на нашите програмни инструкции по време на изпълнение или с прости думи изключение е грешка.
Синтаксис на обработка на изключения в PL/SQL
DECLARE <declarations section> BEGIN <executable command(s)> EXCEPTION <exception handling goes here > WHEN exception1 THEN exception1-handling-statements WHEN exception2 THEN exception2-handling-statements WHEN exception3 THEN exception3-handling-statements ........ WHEN others THEN exception3-handling-statements END;
Тук можем да изброим толкова изключения, колкото искаме да обработваме. Изключението по подразбиране ще се обработва с помощта на „WHEN other THEN“
Пример за обработка на изключения в PL/SQL
Програмата по-долу показва името и адреса на ученик, чийто идентификационен номер е даден. Тъй като в нашата база данни няма ученик със стойност на ID 8, програмата повдига изключението по време на изпълнение NO_DATA_FOUND, което се улавя в блока EXCEPTION.
DECLARE s_id studentS.id%type := 8; s_name studentS.Name%type; s_loc studentS.loc%type; BEGIN SELECT name, loation INTO s_name, s_loc FROM students WHERE id = s_id; DBMS_OUTPUT.PUT_LINE ('Name: '|| s_name); DBMS_OUTPUT.PUT_LINE ('Location: ' || s_loc); EXCEPTION WHEN no_data_found THEN dbms_output.put_line('No such student!'); WHEN others THEN dbms_output.put_line('Oops, Error!'); END;
Изход
No such student! PL/SQL procedure successfully completed.
Тук можем да изброим толкова изключения, колкото искаме да обработваме. Изключението по подразбиране ще се обработва с помощта на „WHEN other THEN ’
Типове изключения в PL/SQL
- Системно дефинирана
- Потребител е отхвърлен
По-нататък в тази статия за обработката на изключения в PL/SQL, нека обсъдим и двата типа подробно.
Системно дефинирана
Дефинирани и поддържани имплицитно от сървъра на Oracle, тези изключения са дефинирани главно в стандартния пакет на Oracle. Всеки път, когато възникне изключение в програмата, сървърът на Oracle съпоставя и идентифицира подходящото изключение от наличния набор от изключения, налични в стандартния пакет на Oracle. По принцип тези изключения са предварително дефинирани в PL/SQL, което се повдига КОГАТО конкретно правило за база данни е нарушено .
Системно дефинираните изключения са разделени допълнително на две категории:
- Именувани системни изключения
- Неименувани системни изключения
Изключения на именувани системи
Именуваните PL/SQL изключения са именувани в стандартния пакет на PL/SQL , следователно разработчикът не трябва да дефинира PL/SQL изключенията в своя код. PL/SQL предоставя много предварително дефинирани именувани изключения, които се изпълняват, когато някое правило за база данни е нарушено от програма. Следващата таблица изброява няколко от важните предварително дефинирани изключения −
Изключение | Грешка в Oracle | SQLCODE | Описание |
ACCESS_INTO_NULL | 06530 | -6530 | Издига се, когато на нулев обект автоматично се присвои стойност. |
CASE_NOT_FOUND | 06592 | -6592 | Издига се, когато не е избран нито един от изборите в клаузата WHEN на оператор CASE и няма клауза ELSE. |
COLLECTION_IS_NULL | 06531 | -6531 | Издига се, когато програма се опитва да приложи методи за събиране, различни от EXISTS към неинициализирана вложена таблица или променлива, или програмата се опитва да присвои стойности на елементите на неинициализирана вложена таблица или променлива. |
DUP_VAL_ON_INDEX | 00001 | -1 | Повишава се, когато дублиращи се стойности се опитват да бъдат съхранени в колона с уникален индекс. |
INVALID_CURSOR | 01001 | -1001 | Издига се, когато се правят опити за извършване на операция с курсор, която не е разрешена, като например затваряне на неотворен курсор. |
INVALID_NUMBER | 01722 | -1722 | Издига се, когато преобразуването на низ от знаци в число не успее, защото низът не представлява валидно число. |
ВХОД_ОТКАЗАН | 01017 | -1017 | Издига се, когато програма се опита да влезе в базата данни с невалидно потребителско име или парола. |
NO_DATA_FOUND | 01403 | +100 | Издига се, когато оператор SELECT INTO не връща редове. |
НЕ_LOGGED_ON | 01012 | -1012 | Издига се, когато се извика база данни, без да е свързана с базата данни. |
ГРЕШКА В ПРОГРАМАТА | 06501 | -6501 | Издига се, когато PL/SQL има вътрешен проблем. |
ROWTYPE_MISMATCH | 06504 | -6504 | Издига се, когато курсорът извлича стойност в променлива с несъвместим тип данни. |
SELF_IS_NULL | 30625 | -30625 | Издига се, когато се извика метод на член, но екземплярът на типа обект не е инициализиран. |
STORAGE_ERROR | 06500 | -6500 | Подава се, когато паметта на PL/SQL свърши или паметта е повредена. |
TOO_MANY_ROWS | 01422 | -1422 | Издига се, когато оператор SELECT INTO връща повече от един ред. |
VALUE_ERROR | 06502 | -6502 | Издига се, когато възникне грешка при аритметика, преобразуване, съкращаване или ограничение на размера. |
ZERO_DIVIDE | 01476 | 1476 | Повишава се, когато се прави опит за разделяне на число на нула. |
Пример
CREATE OR REPLACE PROCEDURE add_new_student (student _id_in IN NUMBER, student _name_in IN VARCHAR2) IS BEGIN INSERT INTO student (student _id, student _name ) VALUES ( student _id_in, student _name_in ); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN raise_application_error (-20001,'Duplicate student _id'); WHEN OTHERS THEN raise_application_error (-20002,'An error occurred.'); END;
Продължавайки в тази статия относно обработката на изключения в PL/SQL, нека разберем какво представляват неименуваните системни изключения.
Неименувани системни изключения
Системните изключения, за които Oracle няма име, са известни като неименувани системни изключения. Тези изключения не се срещат често и са написани с код и свързано съобщение.
По принцип има два начина за обработка на неименувани системни изключения:
1. Използване на манипулатора на изключения WHEN OTHERS
2. Свързване на кода на изключение с име и използването му като именуван изключение.
Някои стъпки, следвани за неименувани системни изключения, са:
- Повишете ги неявно.
- В случай, че не се обработват в „WHEN Others“ тогава, те трябва да бъдат обработвани изрично.
- За да се обработва изрично изключението, те могат да бъдат декларирани с помощта на Pragma EXCEPTION_INIT и обработвани чрез препратка към дефинираното от потребителя име на изключение в секцията за изключение.
Пример за обработка на неименувани изключения с помощта на Pragma EXCEPTION_INIT е предоставен по-късно в статията. Продължавайки в тази статия относно обработката на изключения в PL/SQL, нека разберем дефинираните от потребителя изключения.
Дефинирани от потребителя
Както всички други езици за програмиране, Oracle също ви позволява да декларирате, че рекламите прилагат свои собствени изключения. За разлика от дефинираните от системата изключения, тези изключения се издигат изрично в блока PL/SQL.
Стъпки за деклариране на потребителски дефинирани изключения в базата данни на Oracle
Можем да дефинираме потребителски дефинирани изключения в базата данни на Oracle по следните 3 начина:
- Използване на променлива от тип EXCEPTION
Тук можем да декларираме дефинирано от потребител изключение, като декларираме променлива с тип данни EXCEPTION в нашия код и я издигнем изрично в нашата програма с помощта на оператор RAISE.
- Използване на функцията PRAGMA EXCEPTION_INIT
Можем да дефинираме непредефиниран номер на грешка с променливата от тип данни EXCEPTION
- Използване на метод RAISE_APPLICATION_ERROR
Използвайки този метод, можем да декларираме дефинирано от потребител изключение с нашия собствен персонализиран номер на грешка и съобщение.
Досега може да сте имали груба представа за начините, по които можем да повдигнем потребителски дефинирани изключения в PL/SQL. Ще научим за всеки от гореспоменатите методи с примери по-нататък в тази статия относно обработката на изключения в PL/SQL.
По-нататък в тази статия, нека продължим с демонстрациите за обработка на изключения, дефинирани от потребителя.
Демонстрация на потребителски дефинирани изключения
Продължавайки в тази статия относно обработката на изключения в PL/SQL, нека разберем как да използваме променливата от тип EXCEPTION.
Използване на променлива от тип EXCEPTION
Процесът на деклариране на потребителско дефинирано изключение е разделен на три части и тези 3 части са:
- Декларирайте тип данни за изключение на променлива
- Повишете изключението
- Обработете изключението
Нека напишем код, който да демонстрира подробно горните стъпки.
DECLARE var_dividend NUMBER :=10; var_divisor NUMBER :=0 var_result NUMBER; ex-DivZero EXCEPTION
В горния блок за декларация имаме четири променливи, сред които първите три са променливи от тип данни с нормален номер, а четвъртата, която е ex_DivZero, е специалната променлива за тип данни за изключение. Четвъртото е нашето потребителско изключение.
DECLARE var_dividend NUMBER :=10; var_divisor NUMBER :=0 var_result NUMBER; ex-DivZero EXCEPTION
Горната изпълнителна част на този анонимен блок ще влезе в действие само когато делителят е 0. Ако делителят е нула, както е в нашия случай, грешката ще бъде повдигната и контролът на програмата ще пропусне всички следващи стъпки и ще търси съответстващ манипулатор на изключения. В случай, че открие друга, тя ще извърши съответното действие, в противен случай или ще прекрати програмата, или ще ни подкани с необработена системна грешка.
EXCEPTION WHEN ex_DivZero THEN DBMS_OUTPUT.PUT_LINE(‘ ERROR, The divisor can’t be zero’);
Това е манипулаторът на изключения. Веднага щом потребителят въведе делителя като 0, горният низ от съобщение ще бъде подканен.
Краен код:
DECLARE var_dividend NUMBER :=10; var_divisor NUMBER :=0 var_result NUMBER; ex-DivZero EXCEPTION BEGIN IF var_divisor =0 THEN RAISE ex-DivZero; END IF; Var_result := var_dividend/var_divisor; DBMS_OUTPUT.PUT_LINE (‘Result = ‘ || var_result); BEGIN IF var_divisor =0 THEN RAISE ex-DivZero; END IF; Var_result := var_dividend/var_divisor; DBMS_OUTPUT.PUT_LINE (‘Result = ‘ || var_result); END;
Продължавайки в тази статия относно обработката на изключения в PL/SQL, нека разберем как да използваме метода PRAGMA_EXCEPTION_INIT.
Използване на функция PRAGMA EXCEPTION_INIT
Във функцията PRAGMA EXCEPTION_INIT име на изключение е свързано с номер на грешка в Oracle. Това име може да се използва при проектирането на манипулатора на изключение за грешката. За огромни проекти с много дефинирани от потребителя грешки, PRAGMA EXCEPTION_INIT е най-полезният и подходящ метод.
Синтаксис:
PRAGMA EXCEPTION_INIT(exception_name, -Oracle_error_number);
Пример
DECLARE deadlock_detected EXCEPTION; PRAGMA EXCEPTION_INIT(deadlock_detected, -60); BEGIN NULL; -- Some operation that causes an ORA-00060 error EXCEPTION WHEN deadlock_detected THEN NULL; -- handle the error END;
PRAGMA EXCEPTION_INIT казва на компилатора да свърже име на изключение с номер на грешка в Oracle, както беше споменато по-рано. Позволява ви да се обърнете към всяко вътрешно изключение по име и да напишете конкретен манипулатор за него. Когато видите стек от грешки или поредица от съобщения за грешка, това отгоре е това, което може да бъде хванато и обработено.
Продължавайки в тази статия относно обработката на изключения в PL/SQL, нека разберем как да използваме метода RAISE_APPLICATION_ERROR.
Използване на метод RAISE_APPLICATION_ERROR
Това е процедура, която е вградена в софтуера на oracle. С помощта на тази процедура можем да свържем номер на грешка с персонализирано съобщение за грешка. Комбинирайки както номера за грешка, така и персонализираното съобщение за грешка, може да се състави низ за грешка, който изглежда подобен на онези низове за грешки по подразбиране, които се показват от Oracle, когато се срещне грешка. Процедурата RAISE_APPLICATION_ERROR е намерена в пакета DBMS_STANDARD
Синтаксис
raise_application_error (error_number, message [, {TRUE | FALSE}]);
Пример
/* A trigger trg_emp_detail_chk is created.*/ CREATE OR REPLACE TRIGGER trg_emp_detail_chk /* The trigger timing is declared as BEFORE UPDATE on the EMPLOYEES table.*/ Before UPDATE ON employees DECLARE permission_denied EXCEPTION; BEGIN /*Start of the IF condition checking whether the day of the system time is either Saturday or Sunday or not.*/ IF trim(TO_CHAR(sysdate,'Day')) IN ('Saturday', 'Sunday') THEN raise_application_error(-20000, 'You are not authorized to do any modification in the weekends!!'); /* The procedure raise_application_error is called with the first parameter value as -20000 and the second parameter with a default text stating that the user is not authorized to do any modification in the weekends. */ END IF; END;
С това стигаме до края на тази статия относно „Обработка на изключения в PL/SQL“. Надявам се тази тема да е разбрана добре и да ви е помогнала. Опитайте се да напишете свои собствени кодове и да включите методите, обяснени в тази статия.
Ако искате да се обучавате от професионалисти по тази технология, можете да изберете структурирано обучение от edureka! Вижте това обучение за сертифициране на MySQL DBA от Edureka, доверена компания за онлайн обучение с мрежа от повече от 250 000 доволни учащи, разпространени по целия свят. Този курс ви обучава на основните концепции и усъвършенствани инструменти и техники за управление на данни и администриране на базата данни MySQL. Той включва практическо обучение на концепции като MySQL Workbench, MySQL Server, Data Modeling, MySQL Connector, Database Design, MySQL команден ред, MySQL функции и т.н. В края на обучението ще можете да създавате и администрирате своя собствена база данни MySQL и да управлявате данни.
Имате въпрос към нас? Моля, споменете го в секцията за коментари на тази статия „Обработка на изключения в PL/SQL“ и ние ще се свържем с вас възможно най-скоро.