การจัดการข้อยกเว้นใน Oracle PL/SQL (ตัวอย่าง)

การจัดการข้อยกเว้นใน PL/SQL คืออะไร

ข้อยกเว้นเกิดขึ้นเมื่อกลไก PL/SQL พบคำสั่งที่ไม่สามารถดำเนินการได้เนื่องจากข้อผิดพลาดที่เกิดขึ้นขณะรันไทม์ ข้อผิดพลาดเหล่านี้จะไม่ถูกบันทึกในขณะที่ทำการคอมไพล์ และด้วยเหตุนี้ ข้อผิดพลาดเหล่านี้จึงจำเป็นต้องจัดการเฉพาะในขณะรันไทม์เท่านั้น

ตัวอย่างเช่น หากกลไก PL/SQL ได้รับคำสั่งให้หารตัวเลขใดๆ ด้วย '0' กลไก PL/SQL จะส่งค่านั้นเป็นข้อยกเว้น ข้อยกเว้นจะเกิดขึ้นในเวลารันไทม์โดยกลไก PL/SQL เท่านั้น

ข้อยกเว้นจะทำให้โปรแกรมไม่สามารถดำเนินการต่อไปได้ ดังนั้นเพื่อหลีกเลี่ยงสภาวะดังกล่าว จึงต้องบันทึกและจัดการแยกกัน กระบวนการนี้เรียกว่าเป็น Exception-Handling ซึ่งโปรแกรมเมอร์จะจัดการข้อยกเว้นที่อาจเกิดขึ้นในขณะรันไทม์

ไวยากรณ์การจัดการข้อยกเว้น

ข้อยกเว้นจะได้รับการจัดการที่บล็อก ระดับ เช่น เมื่อมีข้อยกเว้นใดๆ เกิดขึ้นในบล็อกใดๆ การควบคุมจะออกมาจากการดำเนินการส่วนหนึ่งของบล็อกนั้น ข้อยกเว้นจะถูกจัดการที่ส่วนการจัดการข้อยกเว้นของบล็อกนั้น หลังจากจัดการข้อยกเว้นแล้ว ไม่สามารถส่งการควบคุมกลับไปยังส่วนการดำเนินการของบล็อกนั้นอีกครั้งได้

ไวยากรณ์ด้านล่างอธิบายวิธีการจับและจัดการกับข้อยกเว้น

การจัดการข้อยกเว้นใน 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

ประเภทของข้อยกเว้น

ข้อยกเว้นมีอยู่ 2 ประเภท กรุณา/SQL.

  1. ข้อยกเว้นที่กำหนดไว้ล่วงหน้า
  2. ข้อยกเว้นที่ผู้ใช้กำหนด

ข้อยกเว้นที่กำหนดไว้ล่วงหน้า

Oracle ได้กำหนดข้อยกเว้นทั่วไปไว้ล่วงหน้าแล้ว ข้อยกเว้นเหล่านี้มีชื่อข้อยกเว้นเฉพาะและหมายเลขข้อผิดพลาด ข้อยกเว้นเหล่านี้ถูกกำหนดไว้แล้วในแพ็คเกจ 'มาตรฐาน' Oracle- ในโค้ด เราสามารถใช้ชื่อข้อยกเว้นที่กำหนดไว้ล่วงหน้าเหล่านี้เพื่อจัดการได้โดยตรง

ด้านล่างนี้คือข้อยกเว้นบางประการที่กำหนดไว้ล่วงหน้า

ข้อยกเว้น รหัสผิดพลาด เหตุผลข้อยกเว้น
ACCESS_INTO_NULL ออร่า-06530 กำหนดค่าให้กับคุณลักษณะของวัตถุที่ไม่ได้เตรียมใช้งาน
CASE_NOT_FOUND ออร่า-06592 ไม่ตรงตามเงื่อนไขประโยค 'WHEN' ในคำสั่ง CASE และไม่มีการระบุประโยค 'ELSE'
คอลเลกชัน_IS_NULL ออร่า-06531 การใช้วิธีการรวบรวม (ยกเว้นที่มีอยู่) หรือการเข้าถึงคุณลักษณะการรวบรวมในคอลเลกชันที่ไม่ได้กำหนดค่าเริ่มต้น
CURSOR_ALREADY_OPEN ออร่า-06511 กำลังพยายามเปิดก เคอร์เซอร์ ซึ่งเปิดอยู่แล้ว
DUP_VAL_ON_INDEX ออร่า-00001 การจัดเก็บค่าที่ซ้ำกันในคอลัมน์ฐานข้อมูลที่ถูกจำกัดโดยดัชนีเฉพาะ
INVALID_CURSOR ออร่า-01001 การใช้งานเคอร์เซอร์ที่ผิดกฎหมาย เช่น การปิดเคอร์เซอร์ที่ไม่ได้เปิด
INVALID_NUMBER ออร่า-01722 การแปลงอักขระเป็นตัวเลขล้มเหลวเนื่องจากอักขระตัวเลขไม่ถูกต้อง
ไม่พบข้อมูล ออร่า-01403 เมื่อคำสั่ง 'SELECT' ที่มี INTO clause ไม่ดึงข้อมูลแถว
ROW_ไม่ตรงกัน ออร่า-06504 เมื่อชนิดข้อมูลตัวแปรเคอร์เซอร์เข้ากันไม่ได้กับชนิดการส่งคืนเคอร์เซอร์จริง
SUBSCRIPT_BEYOND_COUNT ออร่า-06533 อ้างอิงคอลเลกชันตามหมายเลขดัชนีที่ใหญ่กว่าขนาดคอลเลกชัน
SUBSCRIPT_OUTSIDE_LIMIT ออร่า-06532 การอ้างอิงคอลเลกชันตามหมายเลขดัชนีที่อยู่นอกช่วงที่กฎหมายกำหนด (เช่น: -1)
TOO_MANY_ROWS ออร่า-01422 เมื่อคำสั่ง 'SELECT' พร้อมด้วย INTO clause ส่งคืนมากกว่าหนึ่งแถว
VALUE_ERROR ออร่า-06502 ข้อผิดพลาดทางคณิตศาสตร์หรือข้อจำกัดด้านขนาด (เช่น การกำหนดค่าให้กับตัวแปรที่มีขนาดใหญ่กว่าขนาดของตัวแปร)
ศูนย์_DIVIDE ออร่า-01476 การหารตัวเลขด้วย '0'

ข้อยกเว้นที่ผู้ใช้กำหนด

In Oracleนอกเหนือจากข้อยกเว้นที่กำหนดไว้ล่วงหน้าแล้ว โปรแกรมเมอร์สามารถสร้างข้อยกเว้นของตนเองและจัดการได้ สามารถสร้างได้ในระดับโปรแกรมย่อยในส่วนการประกาศ ข้อยกเว้นเหล่านี้จะมองเห็นได้เฉพาะในโปรแกรมย่อยนั้นเท่านั้น ข้อยกเว้นที่กำหนดไว้ในข้อกำหนดเฉพาะของแพ็คเกจคือข้อยกเว้นสาธารณะ และสามารถมองเห็นได้ทุกที่ที่สามารถเข้าถึงแพ็คเกจได้

ไวยากรณ์: ในระดับโปรแกรมย่อย

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' ถูกกำหนดให้เป็นประเภท 'EXCEPTION' ในข้อกำหนดแพ็คเกจของ -
  • สามารถใช้ในฐานข้อมูลได้ทุกที่ที่สามารถเรียกแพ็คเกจ 'package_name' ได้

PL/SQL เพิ่มข้อยกเว้น

ข้อยกเว้นที่กำหนดไว้ล่วงหน้าทั้งหมดจะถูกยกขึ้นโดยปริยายทุกครั้งที่เกิดข้อผิดพลาด แต่จำเป็นต้องยกข้อยกเว้นที่ผู้ใช้กำหนดไว้อย่างชัดเจน ซึ่งสามารถทำได้โดยใช้คำหลัก 'RAISE' สามารถใช้ในลักษณะใดก็ได้ที่กล่าวถึงด้านล่าง

หากใช้ 'RAISE' แยกต่างหากในโปรแกรม มันจะเผยแพร่ข้อยกเว้นที่เกิดขึ้นแล้วไปยังบล็อกหลัก เฉพาะในบล็อกข้อยกเว้นเท่านั้นที่สามารถใช้ได้ดังที่แสดงด้านล่าง

PL/SQL เพิ่มข้อยกเว้น

CREATE [ PROCEDURE | FUNCTION ]
 AS
BEGIN
<Execution block>
EXCEPTION
WHEN <exception_name> THEN 
             <Handler>
RAISE;
END;

คำอธิบายไวยากรณ์:

  • ในรูปแบบข้างต้น คำหลัก RAISE ถูกใช้ในบล็อกการจัดการข้อยกเว้น
  • เมื่อใดก็ตามที่โปรแกรมพบข้อยกเว้น “Exception_name” ข้อยกเว้นจะถูกจัดการและจะดำเนินการให้เสร็จสิ้นตามปกติ
  • แต่คีย์เวิร์ด 'RAISE' ในส่วนการจัดการข้อยกเว้นจะเผยแพร่ข้อยกเว้นนี้ไปยังโปรแกรมหลัก

หมายเหตุ ในขณะที่เพิ่มข้อยกเว้นให้กับบล็อกหลัก ข้อยกเว้นที่กำลังถูกเพิ่มควรจะมองเห็นได้ที่บล็อกหลักด้วย มิฉะนั้น Oracle จะแสดงข้อผิดพลาด

  • เราสามารถใช้คำหลัก 'RAISE' ตามด้วยชื่อข้อยกเว้นเพื่อเพิ่มข้อยกเว้นที่ผู้ใช้กำหนด/กำหนดไว้ล่วงหน้านั้น สามารถใช้ได้ทั้งในส่วนการดำเนินการและในส่วนการจัดการข้อยกเว้นเพื่อเพิ่มข้อยกเว้น

PL/SQL เพิ่มข้อยกเว้น

CREATE [ PROCEDURE | FUNCTION ] 
AS
BEGIN
<Execution block>
RAISE <exception_name>
EXCEPTION
WHEN <exception_name> THEN
<Handler>
END;

คำอธิบายไวยากรณ์:

  • ในรูปแบบข้างต้น คำหลัก RAISE จะถูกใช้ในส่วนการดำเนินการตามด้วยข้อยกเว้น “Exception_name”
  • สิ่งนี้จะทำให้เกิดข้อยกเว้นเฉพาะนี้ในขณะที่ดำเนินการ และจำเป็นต้องได้รับการจัดการหรือหยิบยกเพิ่มเติม

1 ตัวอย่าง: ในตัวอย่างนี้เราจะมาดูกัน

  • วิธีการประกาศข้อยกเว้น
  • วิธีการยกข้อยกเว้นที่ประกาศไว้และ
  • วิธีเผยแพร่ไปยังบล็อกหลัก

PL/SQL เพิ่มข้อยกเว้น

PL/SQL เพิ่มข้อยกเว้น

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:
/

คำอธิบายรหัส:

  • รหัสบรรทัดที่ 2: ประกาศตัวแปร 'sample_Exception' เป็นประเภท EXCEPTION
  • รหัสบรรทัดที่ 3: ประกาศขั้นตอน Nested_block
  • รหัสบรรทัดที่ 6: พิมพ์ข้อความ “Inside Nested Block”
  • รหัสบรรทัด 7: การพิมพ์คำสั่ง “Raising Sample_Exceptionion from Nested Block”
  • รหัสบรรทัด 8: เพิ่มข้อยกเว้นโดยใช้ 'RAISE Sample_Exception'
  • รหัสบรรทัด 10: ตัวจัดการข้อยกเว้นสำหรับข้อยกเว้น Sample_Exception ในบล็อกที่ซ้อนกัน
  • รหัสบรรทัด 11: การพิมพ์คำสั่ง 'ข้อยกเว้นถูกบันทึกในบล็อกที่ซ้อนกัน' ขึ้นสู่บล็อกหลัก'
  • รหัสบรรทัด 12: เพิ่มข้อยกเว้นให้กับบล็อกหลัก (เผยแพร่ไปยังบล็อกหลัก)
  • รหัสบรรทัด 15: พิมพ์ข้อความ “ภายในบล็อกหลัก”
  • รหัสบรรทัด 16: การพิมพ์คำสั่ง "การเรียกบล็อกที่ซ้อนกัน"
  • รหัสบรรทัด 17: การเรียกขั้นตอน Nested_block
  • รหัสบรรทัด 18: ข้อยกเว้น
  • รหัสบรรทัด 19: ตัวจัดการข้อยกเว้นสำหรับ Sample_Exception ในบล็อกหลัก
  • รหัสบรรทัด 20: การพิมพ์คำสั่ง “ข้อยกเว้นถูกบันทึกในบล็อกหลัก”

ประเด็นสำคัญที่ควรทราบในข้อยกเว้น

  • ในฟังก์ชัน ข้อยกเว้นควรคืนค่าหรือเพิ่มข้อยกเว้นเพิ่มเติมเสมอ อื่น Oracle จะส่งข้อผิดพลาด 'ฟังก์ชันส่งคืนโดยไม่มีค่า' ขณะรันไทม์
  • สามารถกำหนดคำสั่งควบคุมธุรกรรมได้ที่บล็อกการจัดการข้อยกเว้น
  • SQLERRM และ SQLCODE เป็นฟังก์ชันในตัวที่จะให้ข้อความและโค้ดข้อยกเว้น
  • หากไม่มีการจัดการข้อยกเว้น ตามค่าเริ่มต้น ธุรกรรมที่ใช้งานอยู่ในเซสชันนั้นจะถูกย้อนกลับ
  • RAISE_APPLICATION_ERROR (- - ) สามารถใช้แทน RAISE เพื่อเพิ่มข้อผิดพลาดด้วยรหัสผู้ใช้และข้อความ รหัสข้อผิดพลาดควรมากกว่า 20000 และนำหน้าด้วย '-'

สรุป

หลังจากบทนี้แล้ว คุณควรจะสามารถทำงานในด้านต่อไปนี้ของ Pl ได้ SQL ข้อยกเว้น

  • การจัดการกับข้อยกเว้น
  • กำหนดข้อยกเว้น
  • ยกข้อยกเว้น
  • การแพร่กระจายข้อยกเว้น