โดยปกติแล้วใน Oracle Database สาเหตุที่เกิด Error เมื่อจบ Query ด้วยเครื่องหมาย semicolon (;) มักเกิดจาก “บริบทของเครื่องมือที่ใช้” หรือ “ประเภทของคำสั่ง” ครับ
การส่ง Query ผ่าน Programming Language (เช่น Python, Java, PHP)
หากคุณเขียนคำสั่ง SQL ใน Code ของโปรแกรม (เช่น cursor.execute ("SELECT * FROM emp;") ) แล้วใส่ ; ปิดท้าย Oracle จะมองว่า semicolon เป็น ส่วนหนึ่งของคำสั่ง SQL ซึ่งในมาตรฐานของ Oracle SQL ตัว ; ไม่ใช่ส่วนหนึ่งของไวยากรณ์คำสั่ง แต่มันคือ “ตัวแบ่งคำสั่ง” (Statement Terminator) สำหรับเครื่องมือ Tooling เท่านั้น
- วิธีแก้: ตัด
;ออกเมื่อเขียนใน Code- ❌
SELECT * FROM table; - ✅
SELECT * FROM table
- ❌
การใช้ใน Blocks ของ PL / SQL
ใน Oracle จะมีสองโลกที่ทำงานต่างกันเล็กน้อยครับ
- SQL ทั่วไป: ใช้
;เพื่อบอกให้ Tool (เช่น SQL Plus) รันคำสั่ง - PL / SQL (BEGIN…END;) : ภายใน Block นี้
;คือสิ่งที่ บังคับต้องมี เพื่อจบแต่ละบรรทัดคำสั่ง แต่ถ้าคุณใส่;ซ้อนกัน หรือใส่ผิดตำแหน่งในโครงสร้าง Control Flow ก็จะทำให้เกิด Error ทันที - Error ที่พบบ่อย:
ORA-00911: invalid character(มักเกิดจากการที่มี semicolon เกินมาในจุดที่ Database Engine ไม่คาดคิด)
ข้อจำกัดของ Dynamic SQL
หากคุณใช้คำสั่ง EXECUTE IMMEDIATE เพื่อรัน String ที่เป็น SQL
- กฎคือ: ห้ามใส่
;ไว้ใน String นั้นเด็ดขาด ยกเว้นว่าคุณกำลังรัน Anonymous Block (ที่มี BEGIN…END) - ตัวอย่าง:
EXECUTE IMMEDIATE 'CREATE TABLE t (เป็ด INT) ;'— แบบนี้จะ Error เพราะมี;ข้างใน
สรุปการใช้งานที่ถูกต้อง
| บริบท (Context) | ต้องใส่ ; หรือไม่? | เหตุผล |
| SQL*Plus / SQL Developer | ต้องใส่ | เพื่อบอก Tool ให้ส่งคำสั่งไปทำงาน |
| Code (JDBC, Python, etc.) | ห้ามใส่ | ไดรเวอร์จะจัดการส่งคำสั่งให้เอง ; จะกลายเป็นตัวอักษรแปลกปลอม |
| ภายใน PL / SQL Block | ต้องใส่ | เพื่อแยกคำสั่งย่อยภายในโครงสร้าง BEGIN...END |
| Dynamic SQL String | ห้ามใส่ | Oracle Engine มองว่าเป็นอักขระที่ผิดไวยากรณ์ |
คำแนะนำเพิ่มเติม: หากคุณกำลังเจอ Error รหัส ORA-00911, ลองเช็กดูว่ามีช่องว่างแปลก ๆ หรืออักขระพิเศษ (รวมถึง ;) หลุดเข้าไปในตัวแปร String ที่ส่งไปที่ Database หรือเปล่าครับ
อ่านเพิ่มเติม