Stored Procedure ใน MySQL อาจเจอปัญหาเหมือนกับโปรแกรมทั่วไป เช่น ข้อมูลผิดพลาด, หารด้วยศูนย์, หาข้อมูลไม่เจอ หรือการ insert/update ที่ล้มเหลว หากไม่จัดการข้อผิดพลาดเหล่านี้ อาจทำให้ระบบล่ม หรือเกิดข้อมูลไม่ครบถ้วน
MySQL มีคำสั่งที่ชื่อว่า DECLARE HANDLER เพื่อใช้สำหรับ จัดการ error และควบคุม flow เมื่อเกิดเหตุการณ์ที่ไม่คาดคิด
รูปแบบการใช้งาน DECLARE HANDLER
DECLARE handler_type HANDLER
FOR condition_value
statement;
handler_typeเช่นCONTINUE,EXITcondition_valueเช่นSQLEXCEPTION,NOT FOUND,SQLSTATE '23000'statementคือคำสั่งที่จะให้ทำเมื่อเกิด error
ตัวอย่างการใช้งาน
ตัวอย่างที่ 1 ป้องกันการหารด้วยศูนย์
SQL
DELIMITER //
CREATE PROCEDURE safe_divide(IN numerator INT, IN denominator INT)
BEGIN
DECLARE result DECIMAL(10,2);
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
SET result = NULL;
SET result = numerator / denominator;
SELECT result AS ผลลัพธ์;
END //
DELIMITER ;เรียกใช้งาน
SQL
CALL safe_divide(10, 0);ผลลัพธ์
| ผลลัพธ์ |
|---|
| NULL |
ตัวอย่างที่ 2 จัดการกรณีไม่พบข้อมูล (NOT FOUND)
สมมุติว่าเรามีตาราง employees ซึ่งเก็บข้อมูลดังนี้
| employee_id | full_name |
|---|---|
| 1 | สมชาย |
| 2 | อริสา |
ต้องการดึงชื่อพนักงานตาม ID แต่หากไม่พบข้อมูล ก็ให้แสดงว่า “ไม่พบพนักงาน”
SQL
DELIMITER //
CREATE PROCEDURE find_employee(IN emp_id INT)
BEGIN
DECLARE emp_name VARCHAR(100) DEFAULT 'ไม่พบพนักงาน';
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET emp_name = 'ไม่พบพนักงาน';
SELECT full_name INTO emp_name
FROM employees
WHERE employee_id = emp_id;
SELECT emp_name AS ผลลัพธ์;
END //
DELIMITER ;เรียกใช้งาน
SQL
CALL find_employee(99);ผลลัพธ์
| ผลลัพธ์ |
|---|
| ไม่พบพนักงาน |
ประเภทของ HANDLER
CONTINUEให้รันคำสั่งถัดไปต่อแม้เกิด errorEXITหยุดการทำงานของ Procedure ทันทีเมื่อเกิด error
สิ่งที่ตรวจจับได้ใน FOR
SQLEXCEPTIONจับ error SQL ทั่วไป เช่น syntax ผิดSQLWARNINGจับ warning เช่น ค่าไม่ตรงชนิดข้อมูลNOT FOUNDใช้กับSELECT INTO,FETCHไม่เจอข้อมูลSQLSTATE 'xxxxxx'จับ error code เฉพาะเจาะจง
หมายเหตุ
- ต้อง
DECLARE HANDLERก่อนคำสั่งอื่นภายในBEGIN ... END - ใช้
CONTINUEอย่างระมัดระวัง เพราะจะไม่หยุด Procedure เมื่อเกิด error - อย่าลืมตรวจสอบ
NULLในผลลัพธ์ที่ได้จาก HANDLER ถ้าใช้กับ OUT parameter