PL / SQL - ข้อยกเว้น
ในบทนี้เราจะพูดถึงข้อยกเว้นใน PL / SQL ข้อยกเว้นคือเงื่อนไขข้อผิดพลาดระหว่างการทำงานของโปรแกรม PL / SQL สนับสนุนโปรแกรมเมอร์เพื่อตรวจจับเงื่อนไขดังกล่าวโดยใช้EXCEPTIONบล็อกในโปรแกรมและมีการดำเนินการที่เหมาะสมกับเงื่อนไขข้อผิดพลาด มีข้อยกเว้นสองประเภท -
- ข้อยกเว้นที่ระบบกำหนด
- ข้อยกเว้นที่ผู้ใช้กำหนด
ไวยากรณ์สำหรับการจัดการข้อยกเว้น
ไวยากรณ์ทั่วไปสำหรับการจัดการข้อยกเว้นมีดังนี้ ที่นี่คุณสามารถระบุข้อยกเว้นได้มากเท่าที่คุณสามารถจัดการได้ ข้อยกเว้นเริ่มต้นจะได้รับการจัดการโดยใช้WHEN others THEN -
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;
ตัวอย่าง
ให้เราเขียนโค้ดเพื่อแสดงแนวคิด เราจะใช้ตารางลูกค้าที่เราสร้างและใช้ในบทก่อนหน้านี้ -
DECLARE
c_id customers.id%type := 8;
c_name customerS.Name%type;
c_addr customers.address%type;
BEGIN
SELECT name, address INTO c_name, c_addr
FROM customers
WHERE id = c_id;
DBMS_OUTPUT.PUT_LINE ('Name: '|| c_name);
DBMS_OUTPUT.PUT_LINE ('Address: ' || c_addr);
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('No such customer!');
WHEN others THEN
dbms_output.put_line('Error!');
END;
/
เมื่อรหัสด้านบนถูกเรียกใช้ที่พรอมต์ SQL จะให้ผลลัพธ์ดังต่อไปนี้ -
No such customer!
PL/SQL procedure successfully completed.
โปรแกรมข้างต้นแสดงชื่อและที่อยู่ของลูกค้าที่ได้รับรหัส เนื่องจากไม่มีลูกค้าที่มีค่า ID 8 ในฐานข้อมูลของเราโปรแกรมจึงเพิ่มข้อยกเว้นรันไทม์NO_DATA_FOUNDซึ่งถูกจับในไฟล์ EXCEPTION block.
การเพิ่มข้อยกเว้น
เซิร์ฟเวอร์ฐานข้อมูลจะเพิ่มข้อยกเว้นโดยอัตโนมัติเมื่อใดก็ตามที่มีข้อผิดพลาดฐานข้อมูลภายใน แต่โปรแกรมเมอร์สามารถยกข้อยกเว้นได้อย่างชัดเจนโดยใช้คำสั่ง RAISE. ต่อไปนี้เป็นไวยากรณ์ง่ายๆสำหรับการเพิ่มข้อยกเว้น -
DECLARE
exception_name EXCEPTION;
BEGIN
IF condition THEN
RAISE exception_name;
END IF;
EXCEPTION
WHEN exception_name THEN
statement;
END;
คุณสามารถใช้ไวยากรณ์ข้างต้นในการเพิ่มข้อยกเว้นมาตรฐาน Oracle หรือข้อยกเว้นที่ผู้ใช้กำหนด ในส่วนถัดไปเราจะให้ตัวอย่างเกี่ยวกับการเพิ่มข้อยกเว้นที่ผู้ใช้กำหนดเอง คุณสามารถเพิ่มข้อยกเว้นมาตรฐาน Oracle ได้ในลักษณะเดียวกัน
ข้อยกเว้นที่ผู้ใช้กำหนด
PL / SQL ช่วยให้คุณกำหนดข้อยกเว้นของคุณเองตามความต้องการของโปรแกรมของคุณ ต้องมีการประกาศข้อยกเว้นที่ผู้ใช้กำหนดแล้วยกขึ้นอย่างชัดเจนโดยใช้คำสั่ง RAISE หรือโพรซีเดอร์DBMS_STANDARD.RAISE_APPLICATION_ERROR.
ไวยากรณ์สำหรับการประกาศข้อยกเว้นคือ -
DECLARE
my-exception EXCEPTION;
ตัวอย่าง
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงแนวคิด โปรแกรมนี้ขอรหัสลูกค้าเมื่อผู้ใช้ป้อน ID ที่ไม่ถูกต้องข้อยกเว้นinvalid_id ถูกยกขึ้น
DECLARE
c_id customers.id%type := &cc_id;
c_name customerS.Name%type;
c_addr customers.address%type;
-- user defined exception
ex_invalid_id EXCEPTION;
BEGIN
IF c_id <= 0 THEN
RAISE ex_invalid_id;
ELSE
SELECT name, address INTO c_name, c_addr
FROM customers
WHERE id = c_id;
DBMS_OUTPUT.PUT_LINE ('Name: '|| c_name);
DBMS_OUTPUT.PUT_LINE ('Address: ' || c_addr);
END IF;
EXCEPTION
WHEN ex_invalid_id THEN
dbms_output.put_line('ID must be greater than zero!');
WHEN no_data_found THEN
dbms_output.put_line('No such customer!');
WHEN others THEN
dbms_output.put_line('Error!');
END;
/
เมื่อรหัสด้านบนถูกเรียกใช้ที่พรอมต์ SQL จะให้ผลลัพธ์ดังต่อไปนี้ -
Enter value for cc_id: -6 (let's enter a value -6)
old 2: c_id customers.id%type := &cc_id;
new 2: c_id customers.id%type := -6;
ID must be greater than zero!
PL/SQL procedure successfully completed.
ข้อยกเว้นที่กำหนดไว้ล่วงหน้า
PL / SQL มีข้อยกเว้นที่กำหนดไว้ล่วงหน้าจำนวนมากซึ่งจะดำเนินการเมื่อกฎฐานข้อมูลใด ๆ ถูกละเมิดโดยโปรแกรม ตัวอย่างเช่นข้อยกเว้นที่กำหนดไว้ล่วงหน้า NO_DATA_FOUND ถูกยกขึ้นเมื่อคำสั่ง SELECT INTO ไม่ส่งคืนแถว ตารางต่อไปนี้แสดงข้อยกเว้นที่กำหนดไว้ล่วงหน้าที่สำคัญบางส่วน -
ข้อยกเว้น | ข้อผิดพลาด Oracle | SQLCODE | คำอธิบาย |
---|---|---|---|
ACCESS_INTO_NULL | 06530 | -6530 | จะเพิ่มขึ้นเมื่อวัตถุว่างถูกกำหนดค่าโดยอัตโนมัติ |
CASE_NOT_FOUND | 06592 | -6592 | จะเพิ่มขึ้นเมื่อไม่มีตัวเลือกใด ๆ ใน WHEN clause ของคำสั่ง CASE และไม่มีส่วนคำสั่ง ELSE |
COLLECTION_IS_NULL | 06531 | -6531 | เพิ่มขึ้นเมื่อโปรแกรมพยายามใช้วิธีการรวบรวมอื่นที่ไม่ใช่ EXISTS กับตารางหรือ varray ที่ซ้อนกันโดยไม่ได้เริ่มต้นหรือโปรแกรมพยายามกำหนดค่าให้กับองค์ประกอบของตารางหรือตัวแปรที่ซ้อนกันโดยไม่ได้เริ่มต้น |
DUP_VAL_ON_INDEX | 00001 | -1 | จะเพิ่มขึ้นเมื่อพยายามเก็บค่าที่ซ้ำกันไว้ในคอลัมน์ที่มีดัชนีเฉพาะ |
INVALID_CURSOR | 01001 | -1001 | จะเพิ่มขึ้นเมื่อมีความพยายามในการดำเนินการเคอร์เซอร์ที่ไม่ได้รับอนุญาตเช่นการปิดเคอร์เซอร์ที่ยังไม่ได้เปิด |
INVALID_NUMBER | 01722 | -1722 | จะเพิ่มขึ้นเมื่อการแปลงสตริงอักขระเป็นตัวเลขล้มเหลวเนื่องจากสตริงไม่ได้แสดงถึงตัวเลขที่ถูกต้อง |
LOGIN_DENIED | 01017 | -1017 | เกิดขึ้นเมื่อโปรแกรมพยายามเข้าสู่ระบบฐานข้อมูลด้วยชื่อผู้ใช้หรือรหัสผ่านที่ไม่ถูกต้อง |
ไม่พบข้อมูล | 01403 | +100 | จะเพิ่มขึ้นเมื่อคำสั่ง SELECT INTO ไม่ส่งกลับแถว |
NOT_LOGGED_ON | 01012 | -1012 | จะเพิ่มขึ้นเมื่อมีการเรียกฐานข้อมูลโดยไม่ได้เชื่อมต่อกับฐานข้อมูล |
PROGRAM_ERROR | 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 | จะเพิ่มขึ้นเมื่อเกิดข้อผิดพลาดทางคณิตศาสตร์การแปลงการตัดทอนหรือ sizeconstraint |
ZERO_DIVIDE | 01476 | พ.ศ. 1476 | จะเพิ่มขึ้นเมื่อมีความพยายามที่จะหารตัวเลขด้วยศูนย์ |