joGet: editable input

ในโลกของการพัฒนาซอฟต์แวร์เชิง Enterprise การควบคุมความถูกต้องและความสมบูรณ์ของข้อมูล (Data Integrity) เป็นสิ่งสำคัญสูงสุด โดยเฉพาะอย่างยิ่งเมื่อเราต้องการให้ผู้ใช้งานสามารถแก้ไขข้อมูลสำคัญได้ แต่ต้องมีการป้องกันการแก้ไขโดยไม่ตั้งใจ (Accidental Overwrite) หรือต้องผ่านกระบวนการตรวจสอบที่ซับซ้อน

สำหรับระบบฐานข้อมูลที่ทรงพลังอย่าง PostgreSQL นั้น เรามีเครื่องมือระดับ Senior Architect ที่เรียกว่า Triggers และ Functions ซึ่งทำหน้าที่เป็นชั้นการควบคุม (Control Layer) ที่ยอดเยี่ยมกว่าการใช้เพียงแค่ `CHECK` Constraint ทั่วไป บทความนี้จะเจาะลึกวิธีการใช้ PostgreSQL เพื่อจำลองกลไก ‘Editable Input’ ที่มีการควบคุมระดับสูง เพื่อให้มั่นใจว่าข้อมูลจะถูกแก้ไขได้เฉพาะเมื่อเป็นไปตามเงื่อนไขที่กำหนดเท่านั้น

💡 หลักการทำงาน: การจำลอง Editable Input ใน PostgreSQL

ในบริบทของ Frontend การป้องกันการแก้ไขข้อมูลจะทำได้ด้วยการตั้งค่า `readonly` attribute แต่ในระดับ Backend ของ PostgreSQL เราต้องใช้ Triggers เพื่อดักจับเหตุการณ์ (Event) ก่อนที่คำสั่ง INSERT หรือ UPDATE จะถูกบันทึกจริง

เราจะสร้าง Function ที่บรรจุตรรกะทางธุรกิจ (Business Logic) และผูกมันเข้ากับ Trigger โดยกำหนดให้ Trigger ทำงาน BEFORE UPDATE ซึ่งหมายความว่าโค้ดจะถูกรันก่อนที่การอัปเดตจะเกิดขึ้น ทำให้เราสามารถตรวจสอบและยกเลิกการเปลี่ยนแปลงได้ทันทีหากเงื่อนไขไม่เป็นไปตามที่กำหนด

🛠️ ตัวอย่างการใช้งาน: การควบคุมสถานะข้อมูล

สมมติว่าเรามีตาราง product_data ที่มีคอลัมน์ status (สถานะ) ซึ่งเป็นข้อมูลสำคัญ และเราต้องการให้สถานะนี้สามารถแก้ไขได้ก็ต่อเมื่อมีการระบุรหัสผู้ดูแลระบบ (Admin ID) ที่ถูกต้องเท่านั้น

SQL

-- 1. สร้าง Function สำหรับตรวจสอบและควบคุมข้อมูล (PL/pgSQL) --
CREATE OR REPLACE FUNCTION validate_product_status()
RETURNS TRIGGER AS $$
BEGIN
    -- ตรวจสอบว่ามีการพยายามแก้ไขสถานะ (status) หรือไม่
    IF NEW.status IS DISTINCT FROM OLD.status THEN
        -- ถ้าสถานะเปลี่ยนไป ต้องตรวจสอบว่าผู้ใช้ที่อัปเดตมีสิทธิ์ (Admin ID = 1) หรือไม่
        IF NEW.status <> OLD.status AND CURRENT_USER <> 'admin_user' THEN
            RAISE EXCEPTION 'Unauthorized: Cannot change product status. Requires admin privileges.';
        END IF;
    END IF;
    -- ถ้าผ่านการตรวจสอบทั้งหมด ให้ดำเนินการอัปเดตต่อ
    RETURN NEW;
END;$$
LANGUAGE plpgsql;

-- 2. สร้าง Trigger เพื่อผูก Function เข้ากับตาราง product_data --
CREATE TRIGGER enforce_status_update
BEFORE UPDATE ON product_data
FOR EACH ROW
EXECUTE FUNCTION validate_product_status();

-- 3. ตัวอย่างการทำงาน: การพยายามแก้ไขโดยไม่มีสิทธิ์ (จะเกิด Error)
-- UPDATE product_data SET status = 'Archived' WHERE product_id = 123;

-- 4. ตัวอย่างการทำงาน: การแก้ไขโดยมีสิทธิ์ (จะสำเร็จ)
-- UPDATE product_data SET status = 'Active' WHERE product_id = 123;

✅ บทสรุปและข้อแนะนำจาก Senior Architect

การใช้ BEFORE TRIGGER ใน PostgreSQL ไม่ได้เป็นเพียงแค่การเขียนโค้ด แต่คือการสร้าง ชั้นความปลอดภัยทางตรรกะ (Logical Security Layer) ที่ทำงานในระดับฐานข้อมูล ซึ่งมีความน่าเชื่อถือสูงกว่าการพึ่งพาการตรวจสอบที่ฝั่ง Application (Client Side) เพียงอย่างเดียว

หากคุณต้องการระบบที่สามารถควบคุมการแก้ไขข้อมูลที่สำคัญ (Editable Input) ได้อย่างสมบูรณ์แบบ การใช้ PostgreSQL Functions และ Triggers คือคำตอบที่เหมาะสมที่สุด เพราะมันช่วยให้คุณสามารถบังคับใช้กฎทางธุรกิจ (Business Rules) ได้อย่างเข้มงวด ไม่ว่าผู้ใช้จะเข้าถึงผ่านช่องทางใดก็ตาม