ข้อผิดพลาดทางไวยากรณ์เนื่องจากการใช้คำสงวนเป็นชื่อตารางหรือคอลัมน์ใน MySQL
ฉันกำลังพยายามเรียกใช้แบบสอบถาม MySQL อย่างง่ายดังต่อไปนี้:
INSERT INTO user_details (username, location, key)
VALUES ('Tim', 'Florida', 42)
แต่ฉันได้รับข้อผิดพลาดต่อไปนี้:
ข้อผิดพลาด 1064 (42000): คุณมีข้อผิดพลาดในไวยากรณ์ SQL ของคุณ ตรวจสอบคู่มือที่สอดคล้องกับเวอร์ชันเซิร์ฟเวอร์ MySQL ของคุณสำหรับไวยากรณ์ที่เหมาะสมที่จะใช้ใกล้
'key) VALUES ('Tim', 'Florida', 42)'
บรรทัดที่ 1
ฉันจะแก้ไขปัญหาได้อย่างไร
คำตอบ
#ปัญหา
ใน MySQL คำพูดบางอย่างเช่นSELECT
, INSERT
, DELETE
ฯลฯ เป็นคำสงวน เนื่องจากมีความหมายพิเศษ MySQL จึงถือว่าเป็นข้อผิดพลาดทางไวยากรณ์เมื่อใดก็ตามที่คุณใช้เป็นชื่อตารางชื่อคอลัมน์หรือตัวระบุประเภทอื่น ๆ เว้นแต่คุณจะล้อมรอบตัวระบุด้วยแบ็กติก
ตามที่ระบุไว้ในเอกสารอย่างเป็นทางการในหัวข้อ10.2 Schema Object Names (เพิ่มการเน้น):
วัตถุบางอย่างภายใน MySQL รวมทั้งฐานข้อมูลตารางดัชนีคอลัมน์นามแฝงดูขั้นตอนการเก็บพาร์ทิชันตารางและชื่อวัตถุอื่น ๆ ที่รู้จักกันเป็นตัวบ่งชี้
...
หากตัวระบุมีอักขระพิเศษหรือเป็นคำสงวนคุณต้องอ้างถึงเมื่อใดก็ตามที่คุณอ้างถึง
...
อักขระเครื่องหมายคำพูดของตัวระบุคือbacktick ("
`
"):
รายการที่สมบูรณ์ของคำหลักและคำสงวนสามารถพบได้ในส่วน10.3 คำหลักและคำสงวน ในหน้านั้นคำที่ตามด้วย "(R)" เป็นคำสงวน คำสงวนบางคำมีอยู่ด้านล่างรวมถึงคำที่มักจะทำให้เกิดปัญหานี้
- เพิ่ม
- และ
- ก่อน
- โดย
- โทร
- กรณี
- เงื่อนไข
- ลบ
- DESC
- อธิบาย
- จาก
- กลุ่ม
- ใน
- ดัชนี
- แทรก
- ช่วงเวลา
- คือ
- สำคัญ
- ชอบ
- LIMIT
- ยาว
- การจับคู่
- ไม่
- OPTION
- หรือ
- ใบสั่ง
- พาร์ทิชัน
- ข้อมูลอ้างอิง
- เลือก
- ตาราง
- ถึง
- อัปเดต
- ที่ไหน
#การแก้ไขปัญหา
คุณมีสองทางเลือก
1. อย่าใช้คำสงวนเป็นตัวระบุ
วิธีแก้ไขที่ง่ายที่สุดคือหลีกเลี่ยงการใช้คำสงวนเป็นตัวระบุ คุณอาจพบชื่อที่สมเหตุสมผลอื่นสำหรับคอลัมน์ของคุณที่ไม่ใช่คำสงวน
การทำเช่นนี้มีข้อดีอยู่สองประการ:
ช่วยขจัดความเป็นไปได้ที่คุณหรือผู้พัฒนารายอื่นที่ใช้ฐานข้อมูลของคุณจะเขียนข้อผิดพลาดทางไวยากรณ์โดยไม่ได้ตั้งใจเนื่องจากลืมหรือไม่ทราบว่าตัวระบุเฉพาะเป็นคำสงวน มีคำสงวนมากมายใน MySQL และนักพัฒนาส่วนใหญ่ไม่น่าจะรู้ทั้งหมด การไม่ใช้คำเหล่านี้ตั้งแต่แรกคุณจะไม่ทิ้งกับดักไว้สำหรับตัวคุณเองหรือนักพัฒนาในอนาคต
วิธีการอ้างถึงตัวระบุแตกต่างกันระหว่างภาษา SQL ในขณะที่ MySQL ใช้ backticks สำหรับการอ้างถึงตัวระบุโดยค่าเริ่มต้น SQL ที่สอดคล้องกับ ANSI (และแน่นอน MySQL ในโหมด ANSI SQL ตามที่ระบุไว้ที่นี่ ) ใช้เครื่องหมายคำพูดคู่สำหรับการอ้างอิงตัวระบุ ด้วยเหตุนี้การสืบค้นที่อ้างถึงตัวระบุที่มี backticks จึงไม่สามารถพกพาไปยังภาษา SQL อื่น ๆ ได้อย่างง่ายดาย
เพื่อลดความเสี่ยงของความผิดพลาดในอนาคตโดยทั่วไปนี่เป็นแนวทางการดำเนินการที่ชาญฉลาดกว่าการอ้างตัวระบุแบบย้อนกลับ
2. ใช้ backticks
ถ้าเปลี่ยนชื่อตารางหรือคอลัมน์เป็นไปไม่ได้ตัดตัวระบุการกระทำผิดกฎหมายใน backticks ( `
) ตามที่อธิบายในคำพูดก่อนหน้านี้จาก10.2 Schema ชื่อวัตถุ
ตัวอย่างเพื่อสาธิตการใช้งาน (นำมาจาก10.3 Keywords and Reserved Words ):
mysql> CREATE TABLE interval (begin INT, end INT); ERROR 1064 (42000): You have an error in your SQL syntax. near 'interval (begin INT, end INT)'
mysql> CREATE TABLE
interval
(begin INT, end INT); Query OK, 0 rows affected (0.01 sec)
ในทำนองเดียวกันการสืบค้นจากคำถามสามารถแก้ไขได้โดยการตัดคำสำคัญkey
ใน backticks ดังที่แสดงด้านล่าง:
INSERT INTO user_details (username, location, `key`)
VALUES ('Tim', 'Florida', 42)"; ^ ^