ป้ายกำกับ: Pl/pgsql

Rust Error Handling: การใช้งาน Option และการใช้ Operator คำถาม (?) ส่งต่อ Error อย่างสะอาดRust Error Handling: การใช้งาน Option และการใช้ Operator คำถาม (?) ส่งต่อ Error อย่างสะอาด

ในฐานะ System Specialist การออกแบบระบบฐานข้อมูลที่แข็งแกร่ง (Robust) ไม่ได้หมายถึงแค่การเขียน Query ที่ทำงานได้ แต่หมายถึงการออกแบบที่สามารถคาดการณ์และจัดการกับความล้มเหลวที่อาจเกิดขึ้นได้เสมอ (Failure is Expected) ไม่ว่าจะเป็นการที่ข้อมูลขาดหายไป (Optionality) หรือการที่การดำเนินการใดๆ ล้มเหลวกลางคัน (Error Propagation) บทความนี้จะพาคุณไปสำรวจหลักการจัดการข้อผิดพลาดใน PostgreSQL โดยใช้กลไกที่เทียบเคียงกับแนวคิดการจัดการ Optionality และ Error Propagation ที่สะอาด เพื่อให้มั่นใจว่าข้อมูลของคุณจะมีความสมบูรณ์และเป็นไปตาม Transactional Integrity เสมอ

💡 หลักการจัดการ Optionality: การตรวจสอบค่า NULL

ในภาษาโปรแกรมระดับสูง เราใช้ `Option` เพื่อระบุว่าค่าอาจจะไม่มีอยู่จริง (None) ใน PostgreSQL แนวคิดนี้ถูกแทนที่ด้วยการจัดการค่า NULL อย่างเป็นระบบ การล้มเหลวในการตรวจสอบ NULL อาจนำไปสู่ผลลัพธ์ที่ไม่คาดคิด (เช่น การคำนวณที่ผิดพลาด) ดังนั้นการใช้ IS NULL และฟังก์ชัน COALESCE() จึงเป็นสิ่งสำคัญที่สุด

COALESCE() ทำหน้าที่คล้ายกับการให้ค่าเริ่มต้น (Default Value) เมื่อค่าที่ป้อนเข้าไปเป็น NULL ทำให้โค้ดของคุณมีความทนทานมากขึ้น

SQL

-- สถานการณ์: ต้องการแสดงชื่อลูกค้า แต่ถ้าไม่มีให้แสดง 'Guest' แทน NULL<br>SELECT COALESCE(customer.first_name, 'Guest') AS display_name<br>FROM users AS customer<br>WHERE customer.user_id = 101;

🚀 Clean Error Propagation: การควบคุม Transaction ด้วย PL/pgSQL

ในโลกของ Rust เราใช้ Operator `?` เพื่อส่งต่อข้อผิดพลาดอย่างสะอาด (Clean Error Propagation) ใน PostgreSQL เราใช้กลไก Transaction และการจัดการ Exception ภายใน PL/pgSQL เพื่อให้มั่นใจว่าหากส่วนใดส่วนหนึ่งของกระบวนการล้มเหลว การดำเนินการทั้งหมดจะถูกย้อนกลับ (Rollback) อย่างสมบูรณ์

การใช้ BEGIN...EXCEPTION...END หรือการใช้ RAISE EXCEPTION เป็นการบังคับให้โค้ดของเราต้องเตรียมพร้อมรับมือกับข้อผิดพลาดที่อาจเกิดขึ้นจริง ซึ่งเป็นหลักการเดียวกับการออกแบบ API ที่ปลอดภัย

SQL

DO $$<br>DECLARE<br>    user_id_to_process INT := 102;<br>BEGIN<br>    -- 1. พยายามอัปเดตข้อมูล<br>    UPDATE accounts SET balance = balance - 100 WHERE user_id = user_id_to_process;<br>    <br>    -- 2. ตรวจสอบว่ามีการอัปเดตหรือไม่ (จำลองการตรวจสอบความสำเร็จ)<br>    IF NOT FOUND THEN<br>        RAISE EXCEPTION 'User ID % ไม่พบข้อมูล หรือยอดเงินไม่พอ', user_id_to_process;<br>    END IF;<br>    <br>    -- 3. หากสำเร็จ จะทำการบันทึก Log<br>    INSERT INTO transaction_log (user_id, action) VALUES (user_id_to_process, 'SUCCESS');<br>EXCEPTION<br>    WHEN others THEN<br>        -- หากเกิดข้อผิดพลาดใดๆ จะทำการ Rollback และแจ้งข้อผิดพลาดอย่างชัดเจน<br>        RAISE NOTICE 'Transaction failed: %', SQLERRM;<br>        -- ในระบบจริงควรมีการ Log ข้อผิดพลาดที่นี่<br>END $$;

✅ บทสรุป: การสร้างระบบที่ทนทานต่อความล้มเหลว

การทำความเข้าใจและใช้ประโยชน์จากกลไกเหล่านี้ ไม่ใช่แค่การเรียนรู้ Syntax ใหม่ แต่คือการเปลี่ยนกระบวนทัศน์ (Paradigm Shift) ในการคิดถึงโค้ดให้เป็นแบบที่ Failure is Expected หรือคาดหวังว่าจะเกิดข้อผิดพลาดได้เสมอ การยึดมั่นในหลักการจัดการ NULL อย่างรอบคอบและการใช้ Transactional Integrity ใน PostgreSQL จะนำไปสู่การสร้างระบบฐานข้อมูลที่มีความเสถียรสูง ทนทานต่อสภาวะแวดล้อมที่ไม่สมบูรณ์ และพร้อมสำหรับการขยายตัวในระดับ Production Grade อย่างแท้จริง