คู่มืออ้างอิง MySQL ข้ามข้อจำกัดในการอ่านไฟล์ในการโต้ตอบ MySQL ระหว่าง PHP และ MySQL

โหลดข้อมูล INFILE "file_name.txt" ลงในตาราง tbl_name [ ENCLOSED BY ""] ] [(col_name,...)]

คำสั่ง LOAD DATA INFILE อ่านบรรทัดจากไฟล์ข้อความและแทรกลงในตารางด้วยความเร็วสูงมาก หากระบุคีย์เวิร์ด LOCAL ไฟล์จะถูกอ่านจากโฮสต์ไคลเอ็นต์ หากไม่ได้ระบุ LOCAL ไฟล์จะต้องอยู่บนเซิร์ฟเวอร์ (ตัวเลือก LOCAL มีอยู่ใน MySQL เวอร์ชัน 3.22.6 และใหม่กว่า)

หากไฟล์ข้อความที่ต้องอ่านอยู่บนเซิร์ฟเวอร์ ด้วยเหตุผลด้านความปลอดภัย ไฟล์เหล่านี้ควรอยู่ในไดเร็กทอรีฐานข้อมูลหรือผู้ใช้ทุกคนสามารถอ่านได้ นอกจากนี้ หากต้องการใช้คำสั่ง LOAD DATA INFILE กับไฟล์เซิร์ฟเวอร์ คุณต้องมีสิทธิ์ FILE บนโฮสต์เซิร์ฟเวอร์ ดูหัวข้อ 4.2.7 สิทธิ์ที่ได้รับจาก MySQL

ใน MySQL 3.23.49 และ MySQL 4.0.2 คำสั่ง LOCAL จะไม่ทำงานหาก mysqld daemon เริ่มต้นด้วย --local-infile=0 หรือหากไคลเอ็นต์ไม่ได้เปิดใช้งาน LOCAL ดูหัวข้อ 4.2.4 ข้อควรพิจารณาด้านความปลอดภัยที่เกี่ยวข้องกับคำสั่ง LOAD DATA LOCAL

หากระบุคีย์เวิร์ด LOW_PRIORITY การดำเนินการคำสั่ง LOAD DATA นี้จะล่าช้าจนกว่าไคลเอ็นต์อื่นจะอ่านตารางเสร็จแล้ว

หากคุณระบุคีย์เวิร์ด CONCURRENT เมื่อทำงานกับตาราง MyISAM เธรดอื่นๆ จะสามารถดึงข้อมูลจากตารางในขณะที่คำสั่ง LOAD DATA กำลังทำงานอยู่ แน่นอนว่าการใช้ฟีเจอร์นี้จะมีผลกระทบต่อประสิทธิภาพเล็กน้อยต่อการดำเนินการ LOAD DATA แม้ว่าจะไม่มีเธรดอื่นใดกำลังใช้ตารางในเวลาเดียวกันก็ตาม

เมื่อใช้ตัวเลือก LOCAL การดำเนินการอาจช้ากว่าการอนุญาตให้เซิร์ฟเวอร์เข้าถึงไฟล์โดยตรงเล็กน้อย เนื่องจากเนื้อหาของไฟล์จะต้องย้ายจากโฮสต์ไคลเอนต์ไปยังเซิร์ฟเวอร์ ในทางกลับกัน ในกรณีนี้ ไม่จำเป็นต้องมีสิทธิ์ FILE เพื่อโหลดไฟล์ในเครื่อง

เมื่อใช้ MySQL เวอร์ชันก่อน 3.23.24 คำสั่ง LOAD DATA INFILE จะไม่สามารถอ่านจาก FIFO ได้ หากคุณต้องการอ่านจาก FIFO (เช่น gunzip stdout) คุณควรใช้ LOAD DATA LOCAL INFILE

คุณยังสามารถโหลดไฟล์ข้อมูลโดยใช้ยูทิลิตี้ mysqlimport ยูทิลิตี้นี้จะดาวน์โหลดไฟล์โดยการส่งคำสั่ง LOAD DATA INFILE ไปยังเซิร์ฟเวอร์ ตัวเลือก --local ทำให้ mysqlimport อ่านไฟล์ข้อมูลจากโฮสต์ไคลเอ็นต์ คุณสามารถระบุตัวเลือก --compress เพื่อให้ได้ประสิทธิภาพที่ดีขึ้นบนเครือข่ายที่ช้า หากทั้งไคลเอนต์และเซิร์ฟเวอร์รองรับโปรโตคอลการบีบอัดข้อมูล

ในกรณีที่ไฟล์อยู่บนเซิร์ฟเวอร์ ไฟล์หลังจะปฏิบัติตามกฎต่อไปนี้:

  • หากมีการระบุเส้นทางแบบเต็ม (เต็ม) ไปยังไฟล์ เซิร์ฟเวอร์จะใช้เส้นทางนี้โดยไม่มีการเปลี่ยนแปลง
  • หากมีการระบุพาธสัมพัทธ์ไปยังไฟล์ โดยระบุไดเร็กทอรีเริ่มต้นตั้งแต่หนึ่งไดเร็กทอรีขึ้นไป ไฟล์นั้นจะถูกค้นหาโดยสัมพันธ์กับไดเร็กทอรีที่ระบุในไดเร็กทอรีข้อมูลของเซิร์ฟเวอร์ (datadir)
  • หากกำหนดพาธไปยังไฟล์โดยไม่ระบุไดเร็กทอรีเริ่มต้น เซิร์ฟเวอร์จะค้นหาไฟล์นี้ในไดเร็กทอรีของฐานข้อมูลที่กำลังใช้งาน

ตามมาว่าไฟล์ที่ระบุเป็น `./myfile.txt" จะถูกอ่านจากไดเร็กทอรีข้อมูลของเซิร์ฟเวอร์ ในขณะที่ไฟล์ที่ระบุเป็น `myfile.txt" จะถูกอ่านจากไดเร็กทอรีฐานข้อมูลที่ใช้งานอยู่ ตัวอย่างเช่น คำสั่ง LOAD DATA ต่อไปนี้จะอ่านไฟล์ data.txt ในไดเร็กทอรีฐานข้อมูลสำหรับ db1 เนื่องจาก db1 เป็นฐานข้อมูลปัจจุบัน แม้ว่าคำสั่งจะสั่งอย่างชัดเจนให้โหลดไฟล์ลงในตารางฐานข้อมูล db2:

Mysql>ใช้ db1; mysql> โหลดข้อมูล INFILE "data.txt" ลงในตาราง db2.my_table;

คำสำคัญ REPLACE และ IGNORE ควบคุมการประมวลผลบันทึกอินพุตที่ซ้ำกับบันทึกที่มีอยู่ด้วยค่าคีย์ที่ไม่ซ้ำกันเหมือนกัน หากคุณระบุ REPLACE แถวใหม่จะแทนที่แถวที่มีอยู่ด้วยคีย์เฉพาะอันเดียวกัน หากคุณระบุ IGNORE แถวอินพุตที่มีคีย์เฉพาะเดียวกันกับแถวที่มีอยู่จะถูกข้ามไป หากไม่มีการระบุพารามิเตอร์ใดเลย หากตรวจพบค่าคีย์ที่ซ้ำกัน ข้อผิดพลาดจะเกิดขึ้นและไฟล์ข้อความที่เหลือจะถูกละเว้น

หากมีการโหลดข้อมูลจากไฟล์ในเครื่องโดยใช้คำสำคัญ LOCAL เซิร์ฟเวอร์จะไม่สามารถยกเลิกการถ่ายโอนข้อมูลในระหว่างการดำเนินการนี้ได้ ดังนั้นการดำเนินการเริ่มต้นของคำสั่งจะเหมือนกับเมื่อระบุ IGNORE

เมื่อใช้ LOAD DATA INFILE บนตาราง MyISAM ที่ว่างเปล่า ดัชนีที่ไม่ซ้ำทั้งหมดจะถูกสร้างขึ้นในชุดที่แยกต่างหาก (เช่นใน REPAIR) ซึ่งมักจะเพิ่มความเร็วในการโหลดข้อมูล INFILE อย่างมากเมื่อมีดัชนีจำนวนมาก

คำสั่ง LOAD DATA INFILE เป็นส่วนเสริมของ SELECT ... INTO OUTFILE ดูส่วน 6.4.1 ไวยากรณ์คำสั่ง SELECT หากต้องการเขียนข้อมูลจากฐานข้อมูลลงไฟล์ ให้ใช้ SELECT ... INTO OUTFILE หากต้องการอ่านข้อมูลกลับเข้าสู่ฐานข้อมูล จะใช้ LOAD DATA INFILE ไวยากรณ์สำหรับ FIELDS และ LINES จะเหมือนกันในทั้งสองคำสั่ง ทั้งสองส่วนเป็นทางเลือก แต่ถ้าระบุทั้งสองส่วน FIELDS จะต้องนำหน้า LINES

หากมีการระบุ FIELDS แต่ละนิพจน์ย่อย (TERMINATED BY, ENCLOSED BY และ ESCAPED BY) ก็เป็นทางเลือกเช่นกัน แต่ต้องระบุอย่างน้อยหนึ่งรายการ

หากไม่ได้กำหนดคำสั่ง FIELDS พารามิเตอร์จะมีค่าเริ่มต้นเป็นค่าต่อไปนี้:

ฟิลด์ที่สิ้นสุดโดย "\t" ปิดล้อมโดย "" หลบหนีโดย "\\"

หากไม่ได้กำหนดคำสั่ง LINES จะมีโครงสร้างดังต่อไปนี้ตามค่าเริ่มต้น:

บรรทัดที่สิ้นสุดโดย "\n"

กล่าวอีกนัยหนึ่งด้วยการตั้งค่าเริ่มต้น คำสั่ง LOAD DATA INFILE เมื่ออ่านข้อมูลที่ป้อนจะทำงานดังนี้:

  • ค้นหาบรรทัดที่ลงท้ายด้วยอักขระ `\n"
  • แบ่งบรรทัดออกเป็นช่องต่างๆ ตามอักขระแท็บ
  • อย่าคาดหวังว่าฟิลด์จะถูกปิดล้อมด้วยอักขระเครื่องหมายคำพูด
  • ตีความแท็บ บรรทัดใหม่ หรืออักขระ `\" ที่เกิดขึ้นนำหน้าด้วย `\" เป็นตัวอักษรที่เป็นส่วนหนึ่งของค่าฟิลด์

ในทางกลับกัน หากการตั้งค่าเริ่มต้นสำหรับการเขียนเอาต์พุตมีผลอยู่ คำสั่ง SELECT ... INTO OUTFILE จะทำงานดังนี้:

  • แทรกอักขระแท็บระหว่างฟิลด์
  • อย่าปิดช่องด้วยอักขระเครื่องหมายคำพูด ใช้อักขระ `\" เพื่อหลีกอินสแตนซ์ของแท็บ ขึ้นบรรทัดใหม่ หรืออักขระ `\" ที่ปรากฏระหว่างค่าของฟิลด์
  • แทรกบรรทัดใหม่ที่ท้ายแต่ละรายการ

โปรดทราบว่ารายการ FIELDS ESCAPED BY `\" จำเป็นต้องมีแบ็กสแลชสองตัวสำหรับค่าที่ควรอ่านเป็นแบ็กสแลชอันเดียว

ตัวเลือก IGNORE number LINES สามารถใช้เพื่อละเว้นส่วนหัวของชื่อคอลัมน์ที่จุดเริ่มต้นของไฟล์:

Mysql> โหลดข้อมูล INFILE "/tmp/file_name" ลงในตารางทดสอบละเว้น 1 บรรทัด;

เมื่อใช้ SELECT ... INTO OUTFILE ร่วมกับ LOAD DATA INFILE เพื่ออ่านข้อมูลจากฐานข้อมูลลงในไฟล์แล้วกลับจากไฟล์ไปยังฐานข้อมูล ตัวเลือกการประมวลผลฟิลด์และสตริงสำหรับทั้งสองคำสั่งจะต้องเหมือนกัน มิฉะนั้น LOAD DATA INFILE จะไม่สามารถตีความเนื้อหาของไฟล์นี้ได้อย่างถูกต้อง สมมติว่าคำสั่ง SELECT ... INTO OUTFILE ถูกใช้เพื่อเขียนไปยังไฟล์ที่มีฟิลด์คั่นด้วยเครื่องหมายจุลภาค:

Mysql> SELECT * INTO OUTFILE "data.txt" ฟิลด์สิ้นสุดโดย "," จาก ...;

Mysql> โหลดข้อมูล INFILE "data.txt" ลงในตาราง table2 ฟิลด์ที่สิ้นสุดโดย ",";

Mysql> โหลดข้อมูล INFILE "data.txt" ลงในตาราง table2 ฟิลด์ที่สิ้นสุดโดย "\t";

ผลลัพธ์ที่คล้ายกันจะได้รับหากแต่ละบรรทัดอินพุตถูกตีความว่าเป็นฟิลด์ที่แยกจากกัน

คำสั่ง LOAD DATA INFILE ยังสามารถใช้เพื่ออ่านไฟล์ที่ได้รับจากแหล่งภายนอกได้ ตัวอย่างเช่น เขตข้อมูลในไฟล์รูปแบบฐานข้อมูล dBASE จะถูกคั่นด้วยเครื่องหมายจุลภาคและอยู่ในเครื่องหมายคำพูดคู่ หากบรรทัดในไฟล์นี้ลงท้ายด้วยการขึ้นบรรทัดใหม่ คุณสามารถใช้คำสั่งต่อไปนี้เพื่อเขียนไฟล์ ซึ่งจะแสดงตัวเลือกการตั้งค่าที่จัดการฟิลด์และบรรทัด:

Mysql> โหลดข้อมูล INFILE "data.txt" ลงในตาราง tbl_name FIELDS TERMINATED BY , , ENCLOSED BY """ LINES TERMINATED BY "\n";

ตัวเลือกใดๆ ที่จัดการเขตข้อมูลและสตริงสามารถระบุสตริงว่าง ("") ได้ หากสตริงไม่ว่างเปล่าค่าของตัวเลือก FIELDS ENCLOSED BY และ FIELDS ESCAPED BY จะต้องมีอักขระหนึ่งตัว ฟิลด์ที่สิ้นสุดโดยและบรรทัดที่สิ้นสุดโดยค่าตัวเลือกสามารถมีได้มากกว่าหนึ่งอักขระ ตัวอย่างเช่น หากต้องการเขียนบรรทัดที่ลงท้ายด้วยคู่ ``ตัวป้อนบรรทัดส่งคืนบรรทัด'' (เช่นในไฟล์ข้อความ MS DOS หรือ Windows) คุณจะต้องระบุนิพจน์ต่อไปนี้: LINES TERMINATED BY "\r\n"

สร้างเรื่องตลกของตาราง (INT ไม่เป็นโมฆะคีย์หลัก AUTO_INCREMENT, ข้อความตลกไม่เป็นโมฆะ); โหลดข้อมูล INFILE "/tmp/jokes.txt" ลงในตาราง เรื่องตลก ฟิลด์ที่สิ้นสุดโดย ""; บรรทัดสิ้นสุดโดย "\n%%\n" (ตลก);

ตัวเลือก FIELDS ENCLOSED BY จะควบคุมฟิลด์ที่อยู่ภายในอักขระที่ระบุ หากละเว้นพารามิเตอร์ OPTIONALLY ฟิลด์ทั้งหมดจะถูกปิดล้อมในเอาต์พุต (SELECT ... INTO OUTFILE) ด้วยอักขระที่ระบุใน ENCLOSED BY ตัวอย่างของผลลัพธ์ดังกล่าว (โดยใช้เครื่องหมายจุลภาคเป็นตัวคั่นฟิลด์) แสดงไว้ด้านล่าง:

"1", "สตริง", "100.20" "2", "สตริงที่มี , ลูกน้ำ", "102.20" "3", "สตริงที่มีเครื่องหมาย \", "102.20" "4" สตริงที่มี \", เครื่องหมายคำพูดและเครื่องหมายจุลภาค, "102.20"

หากระบุพารามิเตอร์ OPTIONALLY เฉพาะฟิลด์ประเภท CHAR และ VARCHAR เท่านั้นที่จะถูกเน้นด้วยอักขระที่ระบุใน ENCLOSED BY:

1,"สตริง",100.20 2,"สตริงที่มี , ลูกน้ำ",102.20 3,"สตริงที่มีเครื่องหมาย \",102.20 4,"สตริงที่มี \", เครื่องหมายคำพูดและเครื่องหมายจุลภาค",102.20

โปรดทราบว่าลักษณะที่ปรากฏของอักขระ ENCLOSED BY ภายในค่าฟิลด์จะถูกหลีกเลี่ยงโดยนำหน้าด้วยคำนำหน้าจาก ESCAPED BY โปรดทราบว่าหากค่า ESCAPED BY ว่างเปล่า ก็สามารถสร้างเอาต์พุตที่คำสั่ง LOAD DATA INFILE ไม่สามารถอ่านได้อย่างถูกต้อง ตัวอย่างเช่น หากอักขระ Escape เป็นสตริงว่าง ผลลัพธ์ที่แสดงด้านบนจะเป็นดังที่แสดงด้านล่าง โปรดทราบว่าฟิลด์ที่สองในบรรทัดที่สี่มีเครื่องหมายจุลภาคตามหลังเครื่องหมายคำพูด ซึ่ง (ผิดพลาด) ดูเหมือนจะเป็นตัวคั่นฟิลด์นี้:

1,"สตริง",100.20 2,"สตริงที่มี , ลูกน้ำ",102.20 3,"สตริงที่มี " เครื่องหมายคำพูด",102.20 4,"สตริงที่มี ", เครื่องหมายคำพูด และจุลภาค",102.20

สำหรับการป้อนข้อมูล อักขระ ENCLOSED BY (ถ้ามี) จะถูกลบออกจากปลายทั้งสองด้านของค่าฟิลด์ (สิ่งนี้เป็นจริงไม่ว่าจะระบุพารามิเตอร์ OPTIONALLY หรือไม่ก็ตาม พารามิเตอร์ OPTIONALLY จะไม่ถูกนำมาพิจารณาเมื่อทำงานกับข้อมูลอินพุต) หากพบอักขระ ENCLOSED BY ที่นำหน้าด้วยอักขระ ESCAPED BY จะถูกตีความว่าเป็นส่วนหนึ่งของ ค่าปัจจุบันของฟิลด์ นอกจากนี้ อักขระ ENCLOSED BY สองตัวที่เกิดขึ้นภายในฟิลด์จะถูกตีความว่าเป็นอักขระ ENCLOSED BY ตัวเดียว หากฟิลด์นั้นขึ้นต้นด้วยอักขระนั้น ตัวอย่างเช่น หากระบุ ENCLOSED BY """ ราคาจะถูกประมวลผลดังนี้:

"เจ้านาย ""ใหญ่"" -> เจ้านาย "ใหญ่" เจ้านาย "ใหญ่" -> เจ้านาย "ใหญ่" เจ้านาย ""ใหญ่" -> เจ้านาย ""ใหญ่"

ตัวเลือก FIELDS ESCAPED BY ใช้เพื่อควบคุมการเขียนหรือการอ่าน อักขระพิเศษ. หากอักขระ FIELDS ESCAPED BY ไม่ว่างเปล่า จะถูกใช้เป็นคำนำหน้าสำหรับอักขระต่อไปนี้ในเอาต์พุต:

  • ฟิลด์ที่หลบหนีด้วยสัญลักษณ์
  • ฟิลด์ที่ล้อมรอบด้วยสัญลักษณ์
  • อักขระตัวแรกของ FIELDS TERMINATED BY และ LINES TERMINATED BY ค่า
  • อักขระ ASCII 0 (จริงๆ แล้ว ASCII `0" เขียนไว้หลังอักขระ Escape ไม่ใช่ไบต์ที่มีค่าเป็นศูนย์)

หากอักขระ FIELDS ESCAPED BY ว่างเปล่า จะไม่มีอักขระใดถูก Escape ในความเป็นจริงการระบุอักขระหลีกที่ว่างเปล่าไม่มีประโยชน์โดยเฉพาะอย่างยิ่งหากค่าฟิลด์ในข้อมูลที่ประมวลผลมีอักขระใด ๆ ในรายการด้านบน

หากอักขระ FIELDS ESCAPED BY ไม่ว่างเปล่า ในกรณีของข้อมูลที่ป้อน การปรากฏของอักขระดังกล่าวจะถูกลบออก และอักขระที่ตามหลังการเกิดขึ้นดังกล่าวจะถูกนำไปใช้ตามตัวอักษรโดยเป็นส่วนหนึ่งของค่าฟิลด์ ข้อยกเว้นคือ Escape `0" หรือ `N" (เช่น \0 หรือ \N หากอักขระ Escape เป็น `\") ลำดับเหล่านี้ตีความว่าเป็น ASCII 0 (ไบต์ค่า Null) และ NULL ดูกฎสำหรับการจัดการค่า NULL ด้านล่าง .

เพื่อรับมากขึ้น ข้อมูลครบถ้วนสำหรับไวยากรณ์ของอักขระหลีก `\" โปรดดูส่วน 6.1.1 ตัวอักษร: การแสดงสตริงและตัวเลข

ในบางกรณี ตัวเลือกการประมวลผลฟิลด์และแถวโต้ตอบ:

  • ถ้า LINES TERMINATED BY เป็นสตริงว่าง และ FIELDS TERMINATED BY ไม่ใช่สตริงว่าง บรรทัดก็จะลงท้ายด้วยอักขระ FIELDS TERMINATED BY
  • หากทั้ง FIELDS TERMINATED BY และ FIELDS ENCLOSED BY ว่างเปล่า ("") จะใช้รูปแบบสตริงคงที่ (ไม่มีตัวคั่น) รูปแบบโทรศัพท์พื้นฐานไม่มีตัวคั่นระหว่างฟิลด์ แต่เมื่ออ่านและเขียนค่าคอลัมน์ จะใช้ความกว้าง ``เอาต์พุต'' ของคอลัมน์แทน ตัวอย่างเช่น หากคอลัมน์ถูกประกาศเป็น INT(7) ค่าสำหรับคอลัมน์นั้นจะถูกเขียนโดยใช้ฟิลด์กว้าง 7 อักขระ ค่าอินพุตสำหรับคอลัมน์นี้ได้มาจากการอ่านอักขระ 7 ตัว รูปแบบสตริงคงที่ยังส่งผลต่อการจัดการค่า NULL (ดูด้านล่าง) โปรดทราบว่ารูปแบบขนาดคงที่จะไม่ทำงานเมื่อใช้ชุดอักขระแบบหลายไบต์

ค่า NULL จะได้รับการปฏิบัติแตกต่างกันไปขึ้นอยู่กับตัวเลือก FIELDS และ LINES ที่ใช้:

  • สำหรับค่า FIELDS และ LINES เริ่มต้น NULL จะถูกเขียนเป็น \N สำหรับเอาต์พุต และ \N จะถูกอ่านเป็น NULL สำหรับอินพุต (สมมติว่าอักขระ ESCAPED BY คือ `\")
  • หาก FIELDS ENCLOSED BY ไม่ว่างเปล่า ฟิลด์ที่มีค่าเป็นคำที่เป็นตัวอักษร NULL จะถูกอ่านเป็นค่า NULL (ตรงข้ามกับคำว่า NULL ที่อยู่ระหว่างอักขระ FIELDS ENCLOSED BY ซึ่งอ่านเป็นสตริง "NULL")
  • หาก FIELDS ESCAPED BY ว่างเปล่า NULL จะถูกเขียนเป็นคำว่า NULL
  • ในรูปแบบสตริงคงที่ (ซึ่งเกิดขึ้นหากทั้ง FIELDS TERMINATED BY และ FIELDS ENCLOSED BY specifiers ว่างเปล่า) NULL จะถูกเขียนเป็นสตริงว่าง โปรดทราบว่าการดำเนินการนี้ทำให้ค่า NULL และสตริงว่างในตารางที่กำหนดแยกไม่ออกเมื่อเขียนลงในไฟล์ เนื่องจากทั้งสองค่าถูกเขียนเป็นสตริงว่าง หากคุณต้องการให้ค่าเหล่านี้แตกต่างออกไปเมื่ออ่านไฟล์คุณไม่ควรใช้รูปแบบโทรศัพท์พื้นฐาน

บางกรณีไม่รองรับคำสั่ง LOAD DATA INFILE:

  • แถวที่มีขนาดคงที่ (FIELDS TERMINATED BY และ FIELDS ENCLOSED BY ว่างเปล่าทั้งคู่) และคอลัมน์ BLOB หรือ TEXT
  • หากมีการระบุตัวคั่นที่เหมือนกับหรือนำหน้าของตัวคั่นอื่น LOAD DATA INFILE จะไม่สามารถตีความอินพุตได้อย่างถูกต้อง ตัวอย่างเช่น คำสั่ง FIELDS ต่อไปนี้อาจทำให้เกิดปัญหา: FIELDS TERMINATED BY """ ENCLOSED BY """
  • หากตัวเลือก FIELDS ESCAPED BY ว่างเปล่า การเกิดขึ้นของอักขระ FIELDS ENCLOSED BY หรือ LINES TERMINATED BY ในค่าฟิลด์ตามด้วยอักขระ FIELDS TERMINATED BY จะทำให้คำสั่ง LOAD DATA INFILE ยุติการอ่านฟิลด์หรือบรรทัดก่อนเวลาอันควร สิ่งนี้เกิดขึ้นเนื่องจากโหลดข้อมูล INFILE ไม่สามารถระบุได้อย่างถูกต้องว่าฟิลด์หรือบรรทัดสิ้นสุดที่ใด

ตัวอย่างต่อไปนี้จะโหลดคอลัมน์ทั้งหมดของตาราง persondata:

Mysql> โหลดข้อมูล INFILE "persondata.txt" ลงในตารางข้อมูลบุคคล

ไม่ได้ระบุรายการฟิลด์ ดังนั้นคำสั่ง LOAD DATA INFILE คาดว่าแถวอินพุตจะเติมแต่ละคอลัมน์ของตาราง สิ่งนี้ใช้ค่า FIELDS และ LINES เริ่มต้น

หากคุณต้องการโหลดเฉพาะบางคอลัมน์ในตาราง คุณต้องระบุรายการคอลัมน์:

Mysql> โหลดข้อมูล INFILE "persondata.txt" ลงในตารางข้อมูลบุคคล (col1,col2,...);

ต้องระบุรายการฟิลด์ในกรณีที่ลำดับของฟิลด์ในไฟล์อินพุตแตกต่างจากลำดับของคอลัมน์ในตารางนี้ มิฉะนั้น MySQL จะไม่สามารถจับคู่ช่องป้อนข้อมูลและคอลัมน์ของตารางได้

หากแถวมีฟิลด์น้อยเกินไป คอลัมน์ที่ไม่มีฟิลด์ในไฟล์อินพุตจะถูกตั้งค่าเป็นค่าเริ่มต้น การกำหนดค่าเริ่มต้นอธิบายไว้ในส่วน 6.5.3 สร้างไวยากรณ์คำสั่งตาราง

ค่าของฟิลด์ว่างถูกตีความแตกต่างจากไม่มีค่า:

  • สำหรับประเภทสตริง คอลัมน์จะถูกตั้งค่าเป็นสตริงว่าง
  • สำหรับประเภทตัวเลข คอลัมน์จะถูกตั้งค่าเป็น 0
  • สำหรับประเภทวันที่และเวลา คอลัมน์จะถูกตั้งค่าเป็นค่าที่สอดคล้องกันของประเภทนั้น ``null'' ดูส่วน 6.2.2 ประเภทข้อมูลวันที่และเวลา

โปรดทราบว่าค่าเหล่านี้เป็นค่าเดียวกับที่จะจบลงในคอลัมน์อันเป็นผลมาจากการกำหนดสตริงว่างให้กับคอลัมน์สตริง ตัวเลข หรือวันที่/เวลาอย่างชัดเจนในคำสั่ง INSERT หรือ UPDATE

คอลัมน์ประเภท TIMESTAMP จะถูกตั้งค่าเป็นวันที่หรือเวลาปัจจุบันเท่านั้น หากคอลัมน์ถูกตั้งค่าเป็น NULL หรือ (สำหรับคอลัมน์ TIMESTAMP แรกเท่านั้น) หากคอลัมน์ TIMESTAMP อยู่นอกรายการฟิลด์ หากมีการระบุรายการดังกล่าว

หากสตริงอินพุตมีฟิลด์มากเกินไป ฟิลด์พิเศษจะถูกละเว้นและจำนวนคำเตือนจะเพิ่มขึ้น

คำสั่ง LOAD DATA INFILE ตีความอินพุตทั้งหมดเป็นสตริง ดังนั้นคุณจึงไม่สามารถระบุค่าตัวเลขสำหรับคอลัมน์ ENUM หรือ SET ได้ในลักษณะเดียวกับคำสั่ง INSERT ต้องระบุค่า ENUM และ SET ทั้งหมดเป็นสตริง!

เมื่อใช้ C API คุณสามารถรับข้อมูลการสืบค้นได้โดยการเรียกใช้ฟังก์ชัน mysql_info() API ที่ส่วนท้ายของการสืบค้น LOAD DATA INFILE รูปแบบของบรรทัดข้อมูลสำหรับกรณีนี้มีดังต่อไปนี้:

บันทึก: 1 ลบแล้ว: 0 ข้าม: 0 คำเตือน: 0

คำเตือนจะออกในสถานการณ์เดียวกันกับเมื่อเขียนค่าด้วยคำสั่ง INSERT (ดูหัวข้อ 6.4.3 ไวยากรณ์คำสั่ง INSERT) ยกเว้นว่าคำสั่ง LOAD DATA INFILE จะสร้างคำเตือนเพิ่มเติมเมื่อสตริงอินพุตมีฟิลด์น้อยเกินไปหรือมากเกินไป คำเตือนจะไม่ถูกจัดเก็บไว้ที่ใด จำนวนคำเตือนสามารถใช้เพื่อตรวจสอบว่าการดำเนินการที่ระบุเสร็จสมบูรณ์ตามปกติเท่านั้น หากคุณต้องการทราบอย่างชัดเจนว่าอะไรทำให้เกิดคำเตือน การเรียกใช้ SELECT ... INTO OUTFILE บนไฟล์อื่นและการเปรียบเทียบผลลัพธ์กับไฟล์อินพุตต้นฉบับเป็นวิธีเดียวที่จะรับข้อมูลนั้น

หากคุณต้องการโหลดข้อมูลเพื่ออ่านจากไปป์ คุณสามารถใช้เคล็ดลับต่อไปนี้:

Mkfifo /mysql/db/x/x chmod 666 /mysql/db/x/x cat /nt/mysql/db/x/x mysql -e "โหลดข้อมูล INFILE "x" ลงในตาราง x" x

เมื่อใช้ MySQL เวอร์ชันเก่ากว่า 3.23.25 สิ่งที่กล่าวข้างต้นสามารถทำได้กับ LOAD DATA LOCAL INFILE เท่านั้น

เพื่อรับมากขึ้น รายละเอียดข้อมูลสำหรับข้อมูลเกี่ยวกับประสิทธิผลของ INSERT เมื่อเปรียบเทียบกับ LOAD DATA INFILE และความเร็วของ LOAD DATA INFILE โปรดดูหัวข้อ 5.2.9 ความเร็วของการสืบค้น INSERT

ความคิดเห็นของผู้ใช้

โพสต์โดย เจสัน ไททัส[ลบ] [แก้ไข]

“คำเตือนจะไม่ถูกเก็บไว้ที่ใด จำนวนคำเตือนสามารถใช้เป็น
บ่งชี้ว่าทุกอย่างเป็นไปด้วยดี"

คุณต้องล้อเล่นฉันแน่ๆ นี่เป็นการลงโทษ DBA หรือไม่? เช่น. - เรา
รู้ว่าปัญหาคืออะไร แต่คุณจะต้องสร้างไฟล์เอาท์พุตและตรวจดูต่อไป
บันทึกนับล้านของคุณเพื่อค้นหา" MySQL ไม่เคยใส่สิ่งเหล่านี้ลงในบันทึกข้อผิดพลาดหรือไม่
พวกเขาอยู่ที่ไหน? ไปข้างหน้าและทำให้มันเป็นตัวเลือก แต่นี่ก็เป็นปัญหาเพียงพอที่จะทำ
ฉันเปลี่ยนกลับไปใช้ Oracle (และนั่นใช้เวลานานมาก)

โพสโดย campbell ในวันศุกร์ที่ 17 พฤษภาคม 2002, @6:24am[ลบ] [แก้ไข]

ประการที่สองนั้น (!) ฉันไม่เข้าใจว่าคุณเป็นอย่างไร
เขียนประโยคนั้นด้วยสีหน้าตรง

โพสโดย Jonathon Padfield ในวันศุกร์ที่ 17 พฤษภาคม 2002, @6:24am[ลบ] [แก้ไข]

นอกจากนี้ยังไม่มีข้อมูลว่าแถวใดถูกข้ามไป
จะได้รับ

โพสโดย เมื่อวันศุกร์ที่ 17 พฤษภาคม 2002, @6:24am[ลบ] [แก้ไข]

คุณลักษณะนี้มีประโยชน์มากเมื่อส่ง
INSERT จากหน้าเว็บ หากผู้ใช้โดน
รีเฟรชและโพสต์ข้อมูลแบบฟอร์มใหม่ซึ่งส่งผลให้
INSERT ต่อมาของข้อมูลคีย์หลักเดียวกัน
บูม แอพพัง ด้วยวิธีนี้ผู้ใช้สามารถ
กด F5 จนหน้าเปลี่ยนเป็นสีฟ้า แล้วพวกเขาก็
จะไม่ทำลายคำสั่ง REPLACE

[ลบ] [แก้ไข]

ฉันมีโฟลเดอร์ MyDB ใน c:\mysql\data
ฉันวาง Data.txt ไว้ที่นั่นและเมื่อฉันดำเนินการ
โหลดข้อมูลภายใน INFILE "Data.txt" ลงในตาราง
MyTable มันบอกว่า: คำสั่งได้ดำเนินการเรียบร้อยแล้ว
แต่ไม่มีค่าใดถูกเพิ่มลงใน MyTable
ฉันอยู่ภายใต้ W2K

โพสโดย van hoof philip ในวันศุกร์ที่ 17 พฤษภาคม 2002, @6:24am[ลบ] [แก้ไข]

ฉันต้องการซิงโครไนซ์ฐานข้อมูลของฉันกับฐานข้อมูลอื่น
ฐานข้อมูลเป็นครั้งคราว ซึ่งหมายความว่าฉัน
จะต้องใช้สิ่ง REPLACE แต่แล้วยังไงล่ะ
บันทึกที่ไม่มีอยู่ในที่ใหม่กว่าอีกต่อไป
ฐานข้อมูล พวกเขาจะถูกลบใน MySQL หรือไม่
มีวิธีลบสิ่งเหล่านี้อัตโนมัติหรือไม่? หรือเป็น
ทางออกเดียวที่จะทิ้งตาราง MySQL ของฉันและสร้างใหม่
ก่อนที่ฉันจะเริ่มโหลด ฉันกำลังใช้ crontab
สคริปต์สำหรับการดำเนินการนี้ จึงไม่มีการโต้ตอบของมนุษย์
เป็นไปได้ในระหว่างการดำเนินการเหล่านี้

โพสโดย เมื่อวันศุกร์ที่ 17 พฤษภาคม 2002, @6:24am[ลบ] [แก้ไข]

เอกสารไม่ชัดเจนว่าเกี่ยวกับอะไร
ถือเป็นคีย์/ดัชนี "ไม่ซ้ำกัน" ในพื้นที่นี้ มัน
การอ้างอิงถึง "แทรก" แต่การแทรกไม่ได้
มีข้อจำกัดเช่นนั้น ฉันได้พบสิ่งนั้นแล้ว
คีย์มีเอกลักษณ์เฉพาะตัวเพียงพอ แต่ฉันต้องเพิ่ม
พรรคที่ฉันไม่ต้องการ บางทีฉันอาจเป็น
ขาดอะไรบางอย่าง....

โพสโดย เมื่อวันศุกร์ที่ 17 พฤษภาคม 2002, @6:24am[ลบ] [แก้ไข]

เป็นเรื่องน่าหงุดหงิดมากที่ได้รับคำเตือนเมื่อได้รับ
การนำเข้าข้อมูลเข้าสู่ฐานข้อมูล MySQL และไม่เป็น
สามารถเข้าถึงข้อมูลใด ๆ เกี่ยวกับคำเตือนได้
MySQL จำเป็นต้องเพิ่มคุณสมบัติที่จะ
รายงานว่าคำเตือนเกี่ยวกับอะไรมากกว่าเพียงแค่
รายงานคำเตือน เป็นการดีที่ข้อมูลเกี่ยวกับ
ควรแจ้งเตือนทันที ที่
บันทึกข้อผิดพลาดอย่างน้อยที่สุดควรเป็น
สร้างขึ้นเพื่อให้ผู้ใช้สามารถเข้าถึงได้

โพสโดย เมื่อวันศุกร์ที่ 17 พฤษภาคม 2002, @6:24am[ลบ] [แก้ไข]

ในหัวข้อ "F5 จนหน้าเปลี่ยนเป็นสีฟ้า"...

สิ่งนี้ควรได้รับการจัดการในแอปพลิเคชัน มัน
ไม่เสียหายอย่างแน่นอนที่จะบอกผู้ใช้ว่า "คุณ"
ป้อนสิ่งนี้แล้ว กรุณาหยุดการรีเฟรช"

จริงๆแล้วเนื่องจากจำนวนผู้ป่วยใจร้อนจำนวนมาก
ออกไปข้างนอกนั่น ดูเหมือนว่าจะเป็นพิเศษ
ความคิดที่ดี.

โพสโดย Larry Irwin ในวันอังคารที่ 20 สิงหาคม 2002, @11:50am[ลบ] [แก้ไข]

การมีตัวเลือกเพิ่มเติมจะเป็นประโยชน์มาก
เพื่อ "ละเว้นข้อจำกัด" ระหว่างการโหลด
กระบวนการ.

โพสโดย เมื่อวันพฤหัสบดีที่ 5 กันยายน 2002, @01:34am[ลบ] [แก้ไข]

มีสิ่งที่จับได้ด้วย "บนโต๊ะ MyISAM ที่ว่างเปล่าทั้งหมด
ดัชนีที่ไม่ซ้ำจะถูกสร้างขึ้นในชุดที่แยกจากกัน"
เนื่องจากกลไกที่ใช้เป็นแบบ "ซ่อมด้วย"
keycache" ซึ่งอาจช้ามากหากคุณมีจำนวนมาก
ดัชนี เราจำเป็นต้องใช้กลไกในการ
หยุดสร้างคีย์แล้วทำการซ่อมแซมด้วย
myisamchk ใช้ "repair with sort" ตามที่อธิบายไว้ใน
ส่วนที่ 5.2.9 (ถ้า คุณสามารถไปทำงาน :-()

โพสโดย เมื่อวันพุธที่ 9 ตุลาคม 2002, @12:43pm[

ไวยากรณ์โหลดข้อมูล INFILE

โหลดข้อมูลเข้าแฟ้ม" ชื่อไฟล์. txt" ลงในตาราง table_name
[ปิดล้อมโดย "]
]
]
[(ชื่อคอลัมน์,...)]
คำสั่ง LOAD DATA INFILE อ่านบรรทัดจากไฟล์ข้อความและโหลดลงในตารางด้วยความเร็วสูงมาก
คุณยังสามารถโหลดไฟล์ข้อมูลโดยใช้ยูทิลิตี้นำเข้า mysql ทำงานโดยการส่งคำสั่ง LOAD data INFILE ไปยังเซิร์ฟเวอร์ ตัวเลือก --local ทำให้ยูทิลิตี้ mysqlimport อ่านไฟล์ข้อมูลจากโฮสต์ไคลเอ็นต์ คุณสามารถระบุอ็อพชัน -compress เพื่อปรับปรุงประสิทธิภาพบนเครือข่ายที่ช้า หากไคลเอ็นต์และเซิร์ฟเวอร์สนับสนุนโปรโตคอลที่บีบอัด
หากระบุคีย์เวิร์ด LOW_PRIORITY การดำเนินการคำสั่ง LOAD DATA จะล่าช้าจนกว่าไคลเอ็นต์อื่นทั้งหมดจะอ่านเสร็จ
หากระบุคีย์เวิร์ด CONCURRENT ด้วยตาราง MyISAM ที่ตรงตามเงื่อนไขการแทรกที่เกิดขึ้นพร้อมกัน (นั่นคือ ไม่มีบล็อกว่างตรงกลางไฟล์) เธรดอื่นจะสามารถดึงข้อมูลจากตารางในเวลาเดียวกันกับที่ LOAD ข้อมูลถูกดำเนินการ การใช้ตัวเลือกนี้มีผลกระทบต่อประสิทธิภาพเล็กน้อยต่อ LOAD DATA แม้ว่าจะไม่มีเธรดอื่นทำงานอยู่บนโต๊ะก็ตาม
หากมีการระบุคีย์เวิร์ด LOCAL จะส่งผลต่อการเชื่อมต่อฝั่งไคลเอ็นต์

  1. หากระบุ LOCAL ไฟล์จะถูกอ่านโดยโปรแกรมไคลเอนต์บนโฮสต์ไคลเอนต์และส่งไปยังเซิร์ฟเวอร์
  2. หากไม่ได้ระบุคำว่า LOCAL ไฟล์ที่ดาวน์โหลดจะต้องอยู่บนโฮสต์เซิร์ฟเวอร์ และเซิร์ฟเวอร์จะอ่านโดยตรง

LOCAL พร้อมใช้งานใน MySQL 3.22.6 และใหม่กว่า
ด้วยเหตุผลด้านความปลอดภัย เมื่ออ่านไฟล์ข้อความที่อยู่บนเซิร์ฟเวอร์ ไฟล์นั้นจะต้องอยู่ในไดเร็กทอรีข้อมูลหรือทุกคนสามารถอ่านได้ นอกจากนี้ หากต้องการใช้โหลดข้อมูลกับไฟล์เซิร์ฟเวอร์ คุณต้องมีสิทธิ์ FILE
การดาวน์โหลดด้วยตัวเลือก LOCAL จะช้ากว่าเมื่อคุณให้เซิร์ฟเวอร์สามารถเข้าถึงไฟล์ที่ดาวน์โหลดได้โดยตรง เนื่องจากในกรณีนี้ เนื้อหาของไฟล์จะถูกถ่ายโอนผ่านเครือข่ายผ่านการเชื่อมต่อไคลเอนต์-เซิร์ฟเวอร์ ในทางกลับกัน ในกรณีนี้ คุณไม่จำเป็นต้องมีสิทธิ์ FILE
เนื่องจาก MySQL 3.23.49 และ MySQL 4.0.2 (4.0.13 บน Windows) LOCAL จะทำงานก็ต่อเมื่อทั้งไคลเอนต์และเซิร์ฟเวอร์อนุญาตเท่านั้น ตัวอย่างเช่น หาก mysqld เปิดตัวด้วยตัวเลือก -local-inf ile=0 LOCAL จะไม่ทำงาน

หากคุณต้องการอ่านจากไพพ์โปรแกรมโดยใช้ LOAD DATA คุณสามารถใช้เทคนิคต่อไปนี้:
mkfifo /mysql/db/x/x.mkfifo
chmod 666 /mysql/db/x/x
แมว< /dev/tcp/10.1.1.12/4711 >/mysql/db/x/x
mysql -e "โหลดข้อมูล INFILE"x1 ลงในตาราง x" x
หากคุณกำลังทำงานกับ MySQL เวอร์ชันก่อนหน้า 3.23.25 เทคนิคนี้สามารถใช้ได้กับโหลดข้อมูลภายในเครื่องเท่านั้น
หากคุณมี MySQL เวอร์ชันเก่ากว่า 3.23.24 คุณจะไม่สามารถอ่านจาก FIFO โดยใช้คำสั่ง LOAD DATA INFILE หากคุณต้องการอ่านจาก FIFO (เช่น จากเอาต์พุต gunzip) ให้ใช้ LOAD DATA LOCAL INFILE แทน
เมื่อค้นหาไฟล์ในระบบไฟล์ เซิร์ฟเวอร์จะปฏิบัติตามกฎต่อไปนี้:

  1. หากมีการกำหนดเส้นทางที่แน่นอน เซิร์ฟเวอร์จะใช้เส้นทางดังกล่าวตามที่เป็นอยู่
  2. หากมีการระบุพาธสัมพัทธ์ที่มีคอมโพเนนต์นำหน้าตั้งแต่หนึ่งรายการขึ้นไป เซิร์ฟเวอร์จะค้นหาไฟล์ที่เกี่ยวข้องกับไดเร็กทอรีข้อมูล
  3. หากระบุชื่อไฟล์โดยไม่มีส่วนประกอบพาธนำ เซิร์ฟเวอร์จะค้นหาไฟล์ในไดเร็กทอรีข้อมูลฐานข้อมูลดีฟอลต์

โปรดทราบว่ากฎเหล่านี้บอกเป็นนัยว่าไฟล์ชื่อ ./myfile.txt ถูกอ่านจากไดเร็กทอรีข้อมูลของเซิร์ฟเวอร์ ในขณะที่ไฟล์ชื่อ myfile,txt ถูกอ่านจากไดเร็กทอรีข้อมูลฐานข้อมูลเริ่มต้น ตัวอย่างเช่น คำสั่ง LOAD DATA INFILE ต่อไปนี้จะอ่านไฟล์ data.txt จากไดเร็กทอรีข้อมูลของ dbl เนื่องจาก dbl เป็นฐานข้อมูลปัจจุบัน แม้ว่าคำสั่งดังกล่าวจะโหลดข้อมูลลงใน db2:
mysql>ใช้ ดับเบิ้ล;
mysql> โหลดข้อมูล INFILE "data.txt" ลงในตาราง db2.my_table;
การควบคุมคำหลัก REPLACE และ IGNORE ทำงานร่วมกับสตริงอินพุตที่ทำซ้ำคีย์ที่ไม่ซ้ำกันที่มีอยู่ในค่า
หากมีการระบุ REPLACE แถวอินพุตจะแทนที่แถวที่มีอยู่ (กล่าวคือ แถวที่มีค่าคีย์หลักหรือค่าคีย์เฉพาะไม่ซ้ำกันกับแถวที่มีอยู่ในตาราง) ดูแทนที่ไวยากรณ์
หากระบุ IGNORE แถวอินพุตที่ซ้ำกันของแถวที่มีอยู่ที่มีค่าคีย์หลักหรือค่าคีย์เฉพาะที่ไม่ซ้ำกันจะถูกข้ามไป หากไม่มีการระบุตัวเลือกใดเลย ลักษณะการทำงานจะขึ้นอยู่กับว่ามีการระบุคีย์เวิร์ดท้องถิ่นหรือไม่ หากไม่มี LOCAL หากตรวจพบคีย์ที่ซ้ำกัน จะเกิดข้อผิดพลาดและไฟล์ข้อความส่วนที่เหลือจะถูกละเว้น หากมี LOCAL การทำงานเริ่มต้นจะเหมือนกับการระบุ IGNORE เนื่องจากเซิร์ฟเวอร์ไม่สามารถหยุดการถ่ายโอนไฟล์ในขณะที่ดำเนินการอยู่
หากคุณต้องการละเว้นข้อจำกัดของคีย์ภายนอกในระหว่างการดำเนินการโหลดข้อมูล คุณสามารถออกคำสั่ง SET FOREIGN_KEY_CHECKS=0 ก่อนที่จะรัน LOAD DATA
หากคุณรัน LOAD DATA บนตาราง MyISAM ที่ว่างเปล่า ดัชนีที่ไม่ซ้ำทั้งหมดจะถูกสร้างขึ้นในงานแยกต่างหาก (สำหรับ REPAIR TABLE) ซึ่งมักจะส่งผลให้โหลดข้อมูลเร็วขึ้นมากเมื่อมีดัชนีจำนวนมาก โดยทั่วไปวิธีนี้จะทำงานได้เร็วมาก แต่ในบางกรณีพิเศษ คุณสามารถสร้างดัชนีได้เร็วยิ่งขึ้นด้วยการปิดใช้งานผ่าน ALTER TABLE...DISABLE KEYS ก่อนโหลด

ลงในตาราง สร้างดัชนีใหม่และเปิดใช้งานโดยใช้ ALTER TABLE... ENABLE KEYS หลังจากการโหลดเสร็จสิ้น
โหลดข้อมูล INFILE เป็นส่วนเสริมของ SELECT...INTO OUTFILE ดูไวยากรณ์ SELECT หากต้องการเขียนข้อมูลจากตารางลงในไฟล์ ให้ใช้ SELECT... INTO OUTFILE หากต้องการอ่านข้อมูลจากไฟล์ลงในตาราง ให้ใช้ LOAD DATA INFILE ไวยากรณ์ของโครงสร้าง FIELDS และ LINES จะเหมือนกันสำหรับทั้งสองคำสั่ง โครงสร้างทั้งสองนี้เป็นทางเลือก แต่ฟิลด์ต้องอยู่ข้างหน้า LINES หากมีการระบุทั้งสองอย่าง
หากมีการระบุโครงสร้าง FIELDS พารามิเตอร์ทั้งหมด (TERMINATED BY, ENCLOSED BY และ ESCAPED BY) ก็เป็นทางเลือกเช่นกัน ยกเว้นข้อกำหนดที่ต้องมีพารามิเตอร์อย่างน้อยหนึ่งตัว
หากไม่ได้ระบุโครงสร้าง FIELDS ค่าเริ่มต้นคือ:
ฟิลด์ที่สิ้นสุดโดย "tf ปิดล้อมโดย" หลบหนีโดย "
หากไม่ได้ระบุโครงสร้าง LINES ค่าเริ่มต้นจะเป็นดังนี้:
บรรทัดสิ้นสุดโดย "n! STARTING BY"
กล่าวอีกนัยหนึ่ง ลักษณะการทำงานเริ่มต้นของ LOAD DATA INFILE เมื่ออ่านอินพุตคือ:

  1. มองหาตัวคั่นบรรทัดที่จุดเริ่มต้นของบรรทัด
  2. อย่าละเว้นคำนำหน้าบรรทัดใดๆ
  3. แบ่งบรรทัดออกเป็นช่องตามอักขระแท็บ
  4. อย่าคาดหวังว่าฟิลด์จะถูกยกมา
  5. ตีความการเกิดขึ้นของอักขระแท็บ การป้อนบรรทัด หรืออักขระ "\" ที่นำหน้าด้วย \ เป็นอักขระสัญพจน์ที่เป็นส่วนหนึ่งของค่าฟิลด์

ในทางกลับกัน SELECT... INTO OUTFILE จะทำงานเช่นนี้ตามค่าเริ่มต้น:

  1. เขียนอักขระแท็บระหว่างฟิลด์
  2. ไม่ล้อมรอบค่าฟิลด์ด้วยเครื่องหมายคำพูด
  • ใช้ *" เพื่อเน้นแท็บ การขึ้นบรรทัดใหม่ หรือ "\ ที่เกิดขึ้นภายในค่าของฟิลด์
  • เขียนอักขระขึ้นบรรทัดใหม่ที่ท้ายบรรทัด
โปรดทราบว่าการเขียน FIELDS ESCAPED BY "W จะทำให้คุณต้องระบุแบ็กสแลชสองตัวสำหรับค่าที่ต้องใช้แบ็กสแลชหนึ่งอันจึงจะอ่านได้
ในบันทึก!
หากคุณสร้างไฟล์ข้อความบนระบบ Windows คุณอาจต้องระบุ LINES TERMINATED BY "rn เพื่ออ่านไฟล์ได้อย่างถูกต้อง เนื่องจากโดยทั่วไปโปรแกรม Windows จะใช้อักขระสองตัวนี้เป็นตัวคั่นบรรทัด บางโปรแกรม เช่น WordPad อาจใช้อักขระ " r" เป็นตัวคั่นบรรทัด หากต้องการอ่านไฟล์ดังกล่าว ให้ใช้ LINES TERMINATED BY "r"
หากทุกบรรทัดของไฟล์ที่คุณกำลังอ่านมีคำนำหน้าทั่วไปที่คุณต้องการละเว้น ให้ใช้ LINES STARTING BY " string_prefixesเพื่อข้ามคำนำหน้านี้ หากบรรทัดไม่มีคำนำหน้า บรรทัดนั้นจะถูกข้ามไปทั้งหมด

ตัวเลือกละเว้น ปริมาณ LINES ใช้เพื่อละเว้นจำนวนบรรทัดที่ระบุที่จุดเริ่มต้นของไฟล์ ตัวอย่างเช่น คุณสามารถใช้ IGNORE I LINES เพื่อข้ามบรรทัดเริ่มต้นที่มีชื่อคอลัมน์:
mysql> โหลดข้อมูล INFILE "/tmp/test.txt" -> ทดสอบลงในตารางโดยไม่สนใจ 1 บรรทัด;
เมื่อคุณใช้ SELECT... INTO OUTFILE ร่วมกับ LOAD DATA INFILE เพื่อเขียนข้อมูลจากฐานข้อมูลไปยังไฟล์ จากนั้นอ่านและโหลดกลับเข้าไปในฐานข้อมูล ตัวเลือกการจัดการแถวและฟิลด์สำหรับทั้งสองคำสั่งจะต้องเหมือนกัน มิฉะนั้น LOAD DATA INFILE จะไม่สามารถตีความเนื้อหาของไฟล์ข้อความได้อย่างถูกต้อง สมมติว่าคุณใช้ SELECT...INTO OUTFILE เพื่อส่งออกข้อมูลไปยังไฟล์ข้อความ โดยแยกฟิลด์ด้วยเครื่องหมายจุลภาค:
mysql> เลือก* เข้าสู่ OUTFILE "data.txt" -> ฟิลด์ที่สิ้นสุดโดย "," -> FROM table2;
หากต้องการอ่านไฟล์ที่คั่นด้วยเครื่องหมายจุลภาคกลับ วิธีที่ถูกต้องในการดำเนินการนี้คือ:
mysql> โหลดข้อมูล INFILE "data.txt1 ลงในตาราง table2 -> ฟิลด์ที่ถูกยกเลิกโดย
หากคุณพยายามอ่านด้วยคำสั่งด้านล่างแทน มันจะไม่ทำงานเนื่องจาก LOAD DATA INFILE จะค้นหาอักขระแท็บระหว่างค่าฟิลด์:
mysql> โหลดข้อมูล INFILE "data.txt" ลงในตาราง table2 -> ฟิลด์ที่สิ้นสุดโดย "t";
ผลลัพธ์ที่เป็นไปได้มากที่สุดคือการตีความสตริงอินพุตเป็นฟิลด์เดียว
โหลดข้อมูล INFILE ยังสามารถใช้เพื่ออ่านไฟล์จากแหล่งภายนอก ตัวอย่างเช่น ไฟล์อาจมีฟิลด์คั่นด้วยเครื่องหมายจุลภาคและอยู่ในเครื่องหมายคำพูดคู่ หากบรรทัดในไฟล์ถูกคั่นด้วยอักขระขึ้นบรรทัดใหม่ ตัวอย่างต่อไปนี้จะแสดงให้เห็นว่าต้องตั้งค่าตัวเลือกตัวคั่นแถวและคอลัมน์เพื่อโหลดไฟล์:
mysql> โหลดข้อมูล INFILE "data.txt" ลงในตารางtable_name-> สนามสิ้นสุดโดย 1,1 ปิดล้อมโดย "" -> เส้นสิ้นสุดโดย"น";
ตัวเลือกใด ๆ ที่ระบุตัวคั่นแถวและคอลัมน์สามารถใช้สตริงว่าง (") เป็นอาร์กิวเมนต์ได้ หากอาร์กิวเมนต์ไม่ใช่สตริงว่าง ค่าสำหรับ FIELDS ENCLOSED BY และ FIELDS ESCAPED BY จะต้องเหมือนกัน อาร์กิวเมนต์สำหรับ FIELDS TERMINATED OPTIONS BY , LINES STARTING BY และ LINES TERMINATED BY สามารถมีความยาวได้มากกว่าหนึ่งอักขระ ตัวอย่างเช่น หากต้องการเขียนบรรทัดโดยแยกด้วยการขึ้นบรรทัดใหม่/การป้อนบรรทัด หรือหากต้องการอ่านไฟล์ที่มีบรรทัดดังกล่าว ให้ระบุ LINES TERMINATED BY "rn"
หากต้องการอ่านไฟล์ที่คั่นด้วยบรรทัดที่มีอักขระ %% คุณสามารถทำสิ่งต่อไปนี้:
mysql> สร้างเรื่องตลกของตาราง
-> (INT ไม่เป็นโมฆะคีย์หลัก AUTO_INCREMENT, -> ข้อความตลกไม่เป็นโมฆะ);

mysql> โหลดข้อมูล INFILE "/tmp/jokes,txf INTO TABLE jokes -> FIELDS TERMINATED BY "" -> LINES TERMINATED BY "\n%%\n" (ตลก);
ช่องที่ล้อมรอบด้วยตัวควบคุมตัวคั่นช่อง (เครื่องหมายคำพูด) ในเอาต์พุต (SELECT... INTO OUTFILE) หากคุณละเว้นคำว่า OPTIONALLY ฟิลด์ทั้งหมดจะถูกล้อมรอบด้วยอักขระที่ระบุใน ENCLOSED BY ตัวอย่างของผลลัพธ์ดังกล่าว (โดยใช้เครื่องหมายจุลภาคเป็นตัวคั่นฟิลด์) แสดงไว้ด้านล่าง:
"1", "สตริง", "100.20"
"2", "สตริงที่มี , ลูกน้ำ", "102.20"
"3", สตริงที่มี \" เครื่องหมายคำพูด", "102.20"
"4", สตริงที่มี \", เครื่องหมายคำพูดและลูกน้ำ", "102.20"
หากคุณระบุทางเลือก อักขระ ENCLOSED BY จะใช้ในการอ้างอิงช่อง CHAR และ VARCHAR เท่านั้น:
1,"สตริง",100.20
3,"สตริงที่มีเครื่องหมาย \",102.20
4,"สตริงที่มี \", เครื่องหมายคำพูดและเครื่องหมายจุลภาค",102.20
โปรดทราบว่าการปรากฏของอักขระที่ระบุใน ENCLOSED BY ภายในค่าฟิลด์จะนำหน้าด้วยอักขระที่ระบุใน ESCAPED BY นอกจากนี้ หากคุณระบุค่าว่างสำหรับ ESCAPED BY อาจเป็นไปได้ว่าไฟล์จะถูกสร้างขึ้นว่า LOAD DATA INFILE จะไม่สามารถโหลดได้อย่างถูกต้อง
ตัวอย่างเช่น หากเว้นว่างอักขระ cancel ผลลัพธ์ด้านบนจะมีลักษณะดังนี้ สังเกตได้ง่ายว่าฟิลด์ที่สองในบรรทัดที่สี่มีเครื่องหมายจุลภาคตามหลังเครื่องหมายคำพูด ซึ่ง (ผิดพลาด) จะปรากฏเป็นตัวคั่นฟิลด์
1,"สตริง",100.20
2,"สตริงที่มีเครื่องหมายจุลภาค",102.20
3,"สตริงที่มี" เครื่องหมายคำพูด",102.20
4,"สตริงที่มีเครื่องหมายคำพูดและเครื่องหมายจุลภาค",102.20
ขณะที่คุณพิมพ์ สัญลักษณ์ ENCLOSED BY (ถ้ามี) จะถูกลบออกจากส่วนท้ายของค่าของฟิลด์ (สิ่งนี้เป็นจริงไม่ว่าจะระบุคำว่า OPTIONALLY หรือไม่ก็ตาม คำนี้ไม่มีผลกระทบเมื่อแปลอินพุต) การปรากฏของอักขระ ENCLOSED BY ที่นำหน้าด้วยอักขระ ESCAPED BY จะถูกตีความว่าเป็นส่วนหนึ่งของค่าฟิลด์ปัจจุบัน
ถ้าฟิลด์ขึ้นต้นด้วยอักขระ ENCLOSED BY อินสแตนซ์ของอักขระนั้นจะถูกตีความว่าเป็นการสิ้นสุดค่าของฟิลด์ก็ต่อเมื่อมีการตามด้วยฟิลด์หรือลำดับ TERMINATED BY เพื่อหลีกเลี่ยงความคลุมเครือเมื่ออักขระ ENCLOSED BY ปรากฏขึ้นภายในค่าฟิลด์ อักขระนั้นสามารถทำซ้ำได้ และจะถูกตีความว่าเป็นอินสแตนซ์เดียวของอักขระ ตัวอย่างเช่น หากระบุ ENCLOSED BY "" ราคาจะถูกประมวลผลดังนี้:
"เจ้านาย ""ใหญ่"" -> เจ้านาย "ใหญ่" เจ้านาย "ใหญ่" -> เจ้านาย "ใหญ่" เจ้านาย ""ใหญ่" -> เจ้านาย ""ใหญ่"
FIELDS ESCAPED BY ควบคุมการอ่านหรือการเขียนอักขระพิเศษ ถ้าอาร์กิวเมนต์ FIELDS ESCAPED BY ไม่ว่างเปล่า อาร์กิวเมนต์จะถูกใช้เป็นคำนำหน้าสำหรับอักขระต่อไปนี้ในเอาต์พุต:

  1. ฟิลด์ที่หลบหนีด้วยสัญลักษณ์
  2. ฟิลด์ที่ล้อมรอบด้วยสัญลักษณ์
  3. ตัวละครตัวแรกของลำดับ FIELDS TERMINATED BY และ LINES TERMINATED BY
  4. ASCII 0 (ซึ่งเขียนหลังอักขระ cancel เป็น ASCII "0" แทนที่จะเป็นไบต์ว่าง)

หากอักขระ FIELDS ESCAPED BY ว่างเปล่า จะไม่มีอักขระใดนำหน้าด้วยอักขระ Escape และ NULL จะถูกส่งออกเป็น NULL แทนที่จะเป็น \N อาจไม่ใช่ความคิดที่ดีที่จะปล่อยให้อาร์กิวเมนต์ FIELDS ESCAPED BY ว่างเปล่า โดยเฉพาะอย่างยิ่งหากค่าฟิลด์ข้อมูลของคุณมีอักขระใดๆ ที่กล่าวถึง
เมื่อป้อน หาก FIELDS ESCAPED BY ไม่ว่างเปล่า เมื่ออักขระนี้ปรากฏในบรรทัดค่า จะถูกลบออก และอักขระต่อไปนี้จะถูกอ่านตามตัวอักษร โดยเป็นส่วนหนึ่งของค่าฟิลด์ ข้อยกเว้นคือลำดับ "0" หรือ "N" (SYS-PAGE-CONTENT หรือ \N ถ้าอักขระหลีกคือ "\") ลำดับเหล่านี้ถูกตีความว่าเป็น ASCII NUL (ไบต์ว่าง) และ NULL ตามลำดับ กฎสำหรับการจัดการ NULL จะอธิบายไว้ภายหลังในส่วนนี้
ข้อมูลเพิ่มเติมเกี่ยวกับไวยากรณ์การยกเลิก "\" สามารถพบได้ในส่วนค่าตามตัวอักษร
ในบางกรณี ตัวเลือกที่ควบคุมช่องและแถวโต้ตอบกัน:

  1. หากมีการระบุสตริงว่างสำหรับ LINES TERMINATED BY และ FIELDS TERMINATED BY ไม่ว่างเปล่า ดังนั้น LINES TERMINATED BY จะเป็นตัวคั่นบรรทัดด้วย
  2. หากทั้งสองฟิลด์สิ้นสุดโดยและฟิลด์ที่ล้อมรอบโดยว่างเปล่า ระบบจะใช้รูปแบบสตริงคงที่ (ไม่มีตัวคั่น) รูปแบบนี้ไม่ใช้ตัวคั่นระหว่างฟิลด์ (แต่สามารถมีตัวคั่นบรรทัดได้) แต่ค่าของคอลัมน์จะถูกเขียนและอ่านโดยใช้ความกว้างของการแสดงคอลัมน์แทน ตัวอย่างเช่น หากคอลัมน์ถูกประกาศเป็น INT(7) ค่าของคอลัมน์จะถูกเขียนลงในเขตข้อมูลเจ็ดอักขระ เมื่อป้อน ค่าคอลัมน์จะถูกดึงข้อมูลโดยการอ่านอักขระเจ็ดตัว

LINES TERMINATED BY ยังคงใช้เพื่อแยกบรรทัด หากแถวไม่มีฟิลด์ทั้งหมด คอลัมน์ที่เหลือจะถูกกำหนดค่าเริ่มต้น หากคุณไม่มีตัวสิ้นสุดบรรทัด ค่าของมันจะต้องตั้งค่าเป็น 1" ในกรณีนี้ ไฟล์ข้อความจะต้องมีฟิลด์ทั้งหมดในแต่ละบรรทัด รูปแบบความยาวบรรทัดคงที่ยังเกี่ยวข้องกับการจัดการค่า NULL ตามที่อธิบายไว้ ด้านล่าง ควรสังเกตว่าความยาวรูปแบบคงที่จะไม่ทำงานหากใช้ชุดอักขระหลายไบต์ (เช่น Unicode)
การจัดการค่า NULL จะแตกต่างกันไปขึ้นอยู่กับตัวเลือก FIELDS และ LINES ที่ใช้:

  1. ด้วยค่า FIELDS และ LINES เริ่มต้น NULL จะถูกเขียนเป็นค่าฟิลด์เป็น \N สำหรับเอาต์พุต และค่า \N เดียวกันจะถูกอ่านเป็น NULL สำหรับอินพุต (สมมติว่าอักขระ ESCAPED BY ถูกตั้งค่าเป็น "\")-
  2. หาก FIELDS ENCLOSED BY ไม่ว่างเปล่า ฟิลด์ที่มีคำตามตัวอักษร NULL จะถูกอ่านเป็น NULL สิ่งนี้แตกต่างจากกรณีที่คำว่า NULL คั่นด้วยอักขระ FIELDS ENCLOSED BY โดยที่ค่าจะอ่านเป็นสตริง "NULL"
  3. ถ้า FIELDS ESCAPED BY ว่างเปล่า NULL จะถูกเขียนเป็นคำว่า NULL
  • ในรูปแบบความยาวสตริงคงที่ (ซึ่งเกิดขึ้นเมื่อทั้ง FIELDS TERMINATED BY และ FIELDS ENCLOSED BY ว่างเปล่า) NULL จะถูกเขียนเป็นสตริงว่าง โปรดทราบว่าสิ่งนี้ทำให้ค่า NULL และแถวว่างในตารางแยกไม่ออกเมื่อเขียนลงในไฟล์ เนื่องจากทั้งคู่เขียนแถวว่าง หากคุณต้องการแยกแยะระหว่างสิ่งเหล่านั้น ให้หลีกเลี่ยงการใช้รูปแบบความยาวบรรทัดคงที่
    ด้านล่างนี้คือบางกรณีที่โหลดข้อมูล INFILE ไม่รองรับ:
    1. กำหนดความยาวแถว (ฟิลด์ที่สิ้นสุดโดยและฟิลด์ที่ปิดโดย NYTYE) เมื่อมีคอลัมน์ TEXT หรือ BLOB
    2. หากคุณระบุตัวคั่นที่เหมือนกับคำนำหน้าของตัวคั่นอื่น LOAD DATA INFILE อาจตีความสตรีมอินพุตไม่ถูกต้อง ตัวอย่างเช่น ตัวเลือกต่อไปนี้จะทำให้เกิดปัญหา:

    ฟิลด์ที่สิ้นสุดโดย "" ปิดล้อมโดย ""

    • หาก FIELDS ESCAPED BY ว่างเปล่า ค่าของฟิลด์ที่มีอักขระ FIELDS ENCLOSED BY OR LINES TERMINATED BY ตามด้วย LINES TERMINATED BY CHARACTER จะทำให้ LOAD DATA INFILE หยุดอ่านไฟล์หรือบรรทัดเร็วเกินไป สิ่งนี้จะเกิดขึ้นเนื่องจากโหลดข้อมูล INFILE ไม่สามารถระบุได้อย่างถูกต้องว่าค่าของฟิลด์หรือแถวสิ้นสุดที่ใด ตัวอย่างต่อไปนี้โหลดคอลัมน์ทั้งหมดของตาราง persondata: mysql> โหลดข้อมูล INFILE "persondata.txt" ลงในตารางข้อมูลบุคคล
      ตามค่าเริ่มต้น เว้นแต่จะมีการระบุรายการคอลัมน์ไว้ที่ส่วนท้ายของคำสั่ง LOAD DATA INFILE แถวอินพุตนั้นคาดว่าจะมีฟิลด์สำหรับแต่ละคอลัมน์ในตาราง หากคุณต้องการโหลดเฉพาะบางคอลัมน์ในตาราง ให้ระบุรายการคอลัมน์:
      mysql> โหลดข้อมูล INFILE "persondata.txt1
      -> เข้าสู่ข้อมูลส่วนบุคคลของตาราง(coll,col2,...);
      คุณต้องระบุรายการคอลัมน์ด้วยหากลำดับของฟิลด์ในไฟล์อินพุตแตกต่างจากลำดับของคอลัมน์ในตาราง มิฉะนั้น MySQL จะไม่สามารถสร้างการแมประหว่างช่องป้อนข้อมูลและคอลัมน์ของตารางได้
      หากไฟล์อินพุตมีฟิลด์ในแถวน้อยเกินไป คอลัมน์ที่หายไปจะได้รับการกำหนดค่าเริ่มต้น การกำหนดค่าเริ่มต้นอธิบายไว้ในไวยากรณ์ CREATE TABLE
      ค่าฟิลด์ว่างจะถูกตีความแตกต่างจากฟิลด์ที่หายไป:
      1. สำหรับประเภทสตริง คอลัมน์ถูกกำหนดให้เป็นสตริงว่าง
      2. สำหรับประเภทตัวเลข คอลัมน์จะถูกกำหนดให้เป็น 0
      3. สำหรับประเภทวันที่และเวลา - คอลัมน์จะถูกตั้งค่าเป็นประเภทที่เกี่ยวข้อง
        ค่า "โมฆะ" ดูประเภทวันที่และเวลา

      ค่าเหล่านี้เป็นค่าเดียวกันกับที่เป็นผลจากการกำหนดสตริงว่างให้กับคอลัมน์ประเภทเหล่านี้อย่างชัดเจนในคำสั่ง INSERT หรือ UPDATE
      ค่าคอลัมน์ TIMESTAMP จะถูกตั้งค่าเป็นวันที่และเวลาปัจจุบันเฉพาะในกรณีที่ตั้งค่าเป็น NULL (นั่นคือ \N) หรือหากคอลัมน์ประเภทนั้นถูกละเว้นจากรายการฟิลด์หากมีการระบุรายการฟิลด์

      LOAD DATA INFILE ถือว่าอินพุตทั้งหมดเป็นอินพุตสตริง ดังนั้นคุณจึงไม่สามารถใช้ค่าตัวเลขสำหรับคอลัมน์ ENUM หรือ SET ตามที่อนุญาตในคำสั่ง INSERT ต้องระบุค่า ENUM หรือ SET ทั้งหมดเป็นสตริง!
      เมื่อคำสั่ง LOAD DATA INFILE เสร็จสมบูรณ์ จะส่งกลับสตริงข้อมูลในรูปแบบต่อไปนี้:
      บันทึก: ฉันลบแล้ว: 0 ข้าม: 0 คำเตือน: เกี่ยวกับ
      หากคุณกำลังทำงานกับ C API คุณสามารถรับข้อมูลเกี่ยวกับคำสั่งนี้ได้โดยการเรียกใช้ฟังก์ชัน mysql_info()
      คำเตือนที่ปรากฏภายใต้เงื่อนไขบางประการจะเหมือนกับคำเตือนที่เกิดขึ้นเมื่อแทรกค่าด้วยคำสั่ง INSERT (ดูหัวข้อ 6.1.4) ยกเว้นว่า LOAD DATA INFILE ยังสร้างคำเตือนว่ามีฟิลด์น้อยเกินไปหรือมากเกินไป คำเตือนจะไม่ถูกเก็บไว้ที่ใด จำนวนคำเตือนสามารถใช้เป็นสัญญาณว่าทุกอย่างเป็นไปด้วยดีเท่านั้น
      ตั้งแต่ MySQL 4.1.1 คุณสามารถใช้ SHOW WARNINGS เพื่อแสดงรายการคำเตือน max_error_count แรกเป็นข้อมูลเกี่ยวกับ อะไรการโหลดผิดพลาด ดูไวยากรณ์แสดงคำเตือน
      ก่อน MySQL 4.1.1 มีเพียงจำนวนคำเตือนเท่านั้นที่บ่งชี้ว่าการโหลดไม่ราบรื่น หากคุณได้รับคำเตือนและต้องการทราบว่าเหตุใดจึงปรากฏขึ้น วิธีเดียวที่จะทำได้คือใช้ SELECT...INTO OUTFILE เพื่อดัมพ์ตารางไปยังไฟล์อื่นและเปรียบเทียบกับไฟล์อินพุตต้นฉบับ

การนำทางผ่านบทช่วยสอน: 1.1 MySQL คืออะไร? 1.2 ทำไมต้องใช้ MySQL? 1.3 MySQL มีความเสถียรแค่ไหน? 1.4 ตาราง MySQL สามารถใหญ่แค่ไหน? 1.5 MySQL, MySQL AB, MySQL-MAX: คืออะไร? 1.6 MySQL ทำงานบนระบบปฏิบัติการใด? 1.7 การแจกแจง MySQL 1.8 พรอมต์บรรทัดคำสั่ง MySQL 2.1 ความรู้เบื้องต้นเกี่ยวกับ MySQL 2.2 การเชื่อมต่อกับเซิร์ฟเวอร์ MySQL 2.3 การป้อนคำสั่งใน MySQL 2.4 การสร้างและการใช้ฐานข้อมูล 2.5 การสร้างฐานข้อมูล MySQL 2.6 การสร้างตาราง MySQL 2.7 การโหลดข้อมูลลงในตาราง MySQL 2.8 การเลือกข้อมูลทั้งหมดจาก MySQL ตาราง 2.9 การเลือกแถวเฉพาะจากตาราง MySQL 2.10 การเลือกคอลัมน์ที่กำหนดเองจากตาราง MySQL 2.11 การเรียงลำดับแถวจากตาราง MySQL 2.12 การคำนวณวันที่ในตาราง MySQL 2.13 การทำงานกับค่า NULL ในตาราง MySQL 2.14 การจับคู่รูปแบบ เทมเพลต SQL 2.15 การนับแถวในเทมเพลต SQL ฟังก์ชัน COUNT() 2.16 การใช้หลายตารางในหนึ่งเดียว แบบสอบถาม SQL 2.17 รับข้อมูลเกี่ยวกับฐานข้อมูลและตาราง MySQL 2.18 ตัวอย่างการสืบค้นทั่วไปใน MySQL 2.19 ค่าสูงสุดสำหรับคอลัมน์ MySQL 2.20 แถวใดเก็บค่าสูงสุดของคอลัมน์ MySQL บางคอลัมน์ 2.21 สูงสุดของคอลัมน์ในกลุ่ม MySQL 2.22 แถว MySQL ใดมีค่าสูงสุด สำหรับกลุ่มเหรอ? 2.23 การใช้ตัวแปรผู้ใช้ใน MySQL 2.24 การใช้ไคลเอนต์ MySQL ในโหมดแบตช์ 3.1 แถวใน MySQL 3.2 ตัวเลขใน MySQL จะเขียนตัวเลขใน MySQL ได้อย่างไร? 3.3 ค่าเลขฐานสิบหกใน MySQL 3.4 ค่า NULL ใน MySQL 3.5 ฐานข้อมูล ตาราง ดัชนี คอลัมน์ และชื่อนามแฝงใน MySQL 3.6 ความละเอียดอ่อนของตัวพิมพ์เล็กและใหญ่ในชื่อ MySQL 3.7 ตัวแปรผู้ใช้ใน MySQL 3.8 ความคิดเห็นใน MySQL 3.9 คำสงวนของ MySQL 4.1 การสำรองฐานข้อมูล MySQL 4.2 ไวยากรณ์ตารางสำรองใน MySQL 4.3 ไวยากรณ์ตารางการคืนค่าใน MySQL 4.4 ไวยากรณ์ตารางตรวจสอบใน MySQL 4.5 ไวยากรณ์ตารางการซ่อมแซมใน MySQL 4.6 ไวยากรณ์ตารางที่ปรับให้เหมาะสมใน MySQL 4.7 วิเคราะห์ไวยากรณ์ตารางใน MySQL 4.8 ไวยากรณ์ล้างข้อมูลใน MySQL 4.9 K ไวยากรณ์ ILL ใน MySQL 4.10 แสดงไวยากรณ์ MySQL 4.11 แสดงไวยากรณ์สถานะตารางใน MySQL 4.12 แสดงสถานะไวยากรณ์ใน MySQL 4.13 แสดงตัวแปรไวยากรณ์ใน MySQL 4.14 back_log 4.15 character_set, character_sets, concurrent_inserts 4.16 Connect_timeout, Delay_key_write, Delayed_insert_limit 4.17 Delayed_insert_time ออก, ขนาดล่าช้า_queue_, flush_time 4.18 have_raid, have_ssl, init_file 4.19 Interactive_timeout, join_buffer_size, key_buffer_size 4.20 ภาษา, log_bin, long_query_time 4.21 lower_case_table_names, max_allowed_packet, max_binlog_cache_size 4.22 max_connections, max_connect_errors, max_delayed_threads 4.23 max_join_size, max_sort_length, max_user _connections 4.24 max_tmp_tables, max_write_lock_count, myisam_sort_buffer_size 4.25 mуisam_max_extra_sоrt_file_size, myisam_max_sort_file_size, net_buffer_length 4.26 net_read_timeout, net_retry_count, net_write_timeout 4.27 open_files_limit, พอร์ต, record_buffer 4.28 protocol_version, record_rnd_buffer, query_buffer_size 4.29 safe_show_databases,skip_networking,skip_show_databases 4.30 ซ็อกเก็ต, sort_buffer,skip_show_databases 4.31 thread_cache_size, tmp_table_size, wait_timeout 4.32 ไวยากรณ์ SHOW PROCESSLIST ใน MySQL 4 33 Syntaxi SHOW GRANTS ใน MySQL 4.34 ไวยากรณ์ SHOW CREATE TABLE ใน MySQL 4.35 ตัวเลือกไฟล์ my.cnf ใน MySQL 5.1 ประเภทคอลัมน์ใน MySQL 5.2 ประเภทตัวเลขใน MySQL 5.3 ประเภทวันที่และเวลาใน MySQL 5 ปัญหา 4 Y2K (2000) และประเภทวันที่ใน MySQL 5.5 ประเภท DATETIME, DATE และ TIMESTAMP ใน MySQL 5.6 ประเภท TIME ใน MySQL 5.7 YEAR ประเภทใน MySQL 5.8 CHAR และประเภทสตริง VARCHAR ใน MySQL 5.9 BLOB และประเภทสตริง TEXT ใน MySQL 5.10 ประเภทสตริง ENUM ใน MySQL 5.11 ประเภทสตริง SET ใน MySQL 5.12 การเลือกประเภทที่ถูกต้องสำหรับคอลัมน์ MySQL 5.13 การใช้ประเภทคอลัมน์จาก DBMS อื่นสำหรับ MySQL 5.14 ข้อกำหนดหน่วยความจำของคอลัมน์ MySQL 6.1 ฟังก์ชั่นสำหรับการใช้ MySQL ใน SELECT และ WHERE 6.2 ตัวดำเนินการที่ไม่ได้พิมพ์ วงเล็บใน MySQL 6.3 การเปรียบเทียบที่ไม่ได้พิมพ์ ตัวดำเนินการใน MySQL 6.4 ตัวดำเนินการเชิงตรรกะใน MySQL 6.5 ฟังก์ชันการแยกสาขาใน MySQL 6.6 ฟังก์ชันสตริงใน MySQL

หลังจากสร้างตารางแล้ว คุณต้องเติมข้อมูลลงในตาราง คำแนะนำและ แทรกมีประโยชน์สำหรับสิ่งนี้ เราจะพูดถึงวิธีการทำงานในภายหลัง แต่สำหรับตอนนี้ ลองคิดถึงข้อมูลที่จำเป็นต้องป้อนลงในตาราง พวกมันมีหน้าตาเป็นอย่างไร?

สมมติว่าบันทึกสัตว์ป่าของคุณอาจมีคำอธิบายดังนี้ โปรดทราบว่า MySQL คาดหวังวันที่ในรูปแบบปี เดือน ซึ่งอาจแตกต่างจากที่คุณคุ้นเคย ควรใส่ปีเป็นตัวเลข 4 หลักจะดีกว่า MySQL มีอัลกอริธึมที่ค่อนข้างซับซ้อนในการจัดการค่าปีที่เป็นตัวเลขสองหลักอย่างถูกต้อง แต่คุณไม่จำเป็นต้องทราบในตอนนี้ ดังนั้นมาป้อนข้อมูลให้ชัดเจนกันดีกว่า ข้อมูลสัตว์ทั้งหมดสำหรับตัวอย่างของเราแสดงอยู่ในตาราง 2.2:

ตารางที่ 2.2. ข้อมูลสัตว์

ชื่อ เจ้าของ สายพันธุ์ เพศ การเกิด ความตาย
ปุย ฮาโรลด์ แมว 1993-02-04
ปุย ฮาโรลด์ แมว 1993-02-04
กรงเล็บ เกวน แมว 1994-03-17
บัฟฟี่ ฮาโรลด์ สุนัข 1989-05-13
ฝาง เบนนี่ สุนัข 1990-08-27
โบว์เซอร์ ไดแอน สุนัข 1989-08-31 1995-07-29
เจี๊ยบ เกวน นก 1998-09-11
วิสต์เลอร์ เกวน นก 1997-12-09
บาง เบนนี่ งู 1996-04-29

เนื่องจากคุณเริ่มต้นด้วยตารางว่าง วิธีที่ง่ายที่สุดในการเติมตารางคือสร้างไฟล์ข้อความที่มีบรรทัดสำหรับสัตว์แต่ละตัวของคุณ จากนั้นจึงโหลดเนื้อหาของไฟล์ลงในตารางด้วยคำสั่งเพียงคำสั่งเดียว

คุณสามารถสร้างไฟล์ข้อความ pet.txt ที่มีหนึ่งรายการต่อบรรทัด โดยระบุค่าที่คั่นด้วยแท็บหยุดตามลำดับที่แสดงรายการคอลัมน์ในคำสั่ง CREATE TABLE สำหรับค่าที่หายไป (เช่น วันที่ไม่ทราบเพศหรือวันที่ตายของสัตว์ที่ยังมีชีวิตอยู่) คุณสามารถใช้ค่า NULL ได้ หากต้องการแสดงเป็นไฟล์ข้อความ ให้ใช้ป้ายกำกับ ตัวอย่างเช่น ข้อความเกี่ยวกับนกวิสต์เลอร์มีลักษณะดังนี้ (ฉันใช้ช่องว่างเพื่อระบุแท็บ):

นกวิสต์เลอร์เกวน 1997-12-09

หากต้องการโหลดข้อมูลจากไฟล์ข้อความ pet.txt ซึ่งอยู่ที่ คอมพิวเตอร์ท้องถิ่น(ไคลเอนต์) และไม่ได้อยู่บนเซิร์ฟเวอร์ เข้าไปในตารางสัตว์เลี้ยง ให้ใช้คำสั่ง LOAD DATA:

Mysql> โหลดข้อมูลในเครื่อง INFILE "pet.txt" ลงในตาราง pet;

คำสำคัญมีความหมายดังนี้ อินไฟล์กำหนดสตริงที่เป็นชื่อของไฟล์ที่จะอ่านข้อมูล เนื่องจากชื่อเป็นสตริง จึงอยู่ในเครื่องหมายคำพูด มิฉะนั้น MySQL จะพยายามประเมินว่าเป็นนิพจน์ตัวเลข ท้องถิ่นบ่งชี้ว่าควรค้นหาไฟล์บนระบบไคลเอ็นต์ไม่ใช่บนเซิร์ฟเวอร์ ลงในตารางสั่งให้โหลดข้อมูลลงในตารางที่ระบุชื่อทันทีหลังคำว่า TABLE (คั่นด้วยช่องว่าง)

คุณสามารถระบุตัวคั่นค่าคอลัมน์และเครื่องหมายจุดสิ้นสุดบรรทัดในคำสั่งได้อย่างชัดเจนหากต้องการ แต่ค่าเริ่มต้นคือแท็บและการป้อนบรรทัด เพียงพอที่จะอ่านไฟล์ pet.txt ได้อย่างถูกต้อง และคุณไม่จำเป็นต้องมีอะไรเพิ่มเติมในตอนนี้

เมื่อคุณต้องการเพิ่มรายการใหม่ทีละรายการ คำแนะนำจะมีประโยชน์ แทรก. ในรูปแบบที่ง่ายที่สุด คุณจะต้องระบุค่าสำหรับแต่ละคอลัมน์ตามลำดับที่แสดงคอลัมน์ในคำสั่ง CREATE TABLE สมมติว่าไดแอนได้รับหนูแฮมสเตอร์ตัวใหม่ ชื่อพัฟบอล คุณสามารถเพิ่มรายการใหม่ได้โดยใช้คำสั่ง INSERT ในลักษณะนี้:

Mysql> ใส่เข้าไปในสัตว์เลี้ยง
-> ค่า ("พัฟบอล", "ไดแอน", "หนูแฮมสเตอร์", "f", "1999-03-30", "NULL");

คำหลักที่นี่ก็ไม่ซับซ้อนเช่นกัน สัตว์เลี้ยง INTO กำหนดว่าตารางใดที่จะแทรกเข้าไป ค่านิยมระบุรายการค่าที่แทรกไว้สำหรับ รายการใหม่ในตาราง ค่าต่างๆ จะถูกแสดงรายการโดยคั่นด้วยเครื่องหมายจุลภาคและทั้งหมดรวมอยู่ในวงเล็บ

โปรดทราบว่าสตริงและค่าวันที่ถูกกำหนดให้เป็นสตริง คุณสามารถแทรก NULL ได้โดยตรง (ไม่ใช่เป็นสตริง) เพื่อแสดงว่าไม่มีค่า

จากตัวอย่างนี้ คุณจะเห็นว่าการโหลดลงในตารางโดยตรงนั้นต้องใช้เวลาในการพิมพ์ค่อนข้างมาก คำแนะนำช่วยประหยัดเวลาได้มาก

ฉันกำลังอธิบายสถานการณ์ที่ค่อนข้างธรรมดา ในช่วงเพนเทสต์ ได้รับการเข้าถึง phpMyAdmin บนโฮสต์ระยะไกล แต่ไม่สามารถเข้าถึงไฟล์ผ่านมันได้ FILE_PRIV=no ที่มีชื่อเสียงฉาวโฉ่ในการตั้งค่า MySQL daemon คือการตำหนิ หลายคนยอมแพ้ในสถานการณ์นี้และเชื่อว่าไฟล์บนโฮสต์ไม่สามารถอ่านได้ด้วยวิธีนี้อีกต่อไป แต่มันก็ไม่ได้เป็นเช่นนั้นเสมอไป

คำเตือน

ข้อมูลทั้งหมดมีไว้เพื่อวัตถุประสงค์ในการให้ข้อมูลเท่านั้น ทั้งบรรณาธิการและผู้เขียนจะไม่รับผิดชอบต่อความเสียหายใด ๆ ที่อาจเกิดขึ้นจากเนื้อหาในบทความนี้

โหมโรง

เมื่อพูดถึงการทำงานร่วมกันของ MySQL DBMS กับระบบไฟล์ พวกเขามักจะจำ:

  • ฟังก์ชัน LOAD_FILE ซึ่งช่วยให้คุณอ่านไฟล์บนเซิร์ฟเวอร์
  • โครงสร้าง SELECT ... INTO OUTFILE ซึ่งสามารถใช้สร้างไฟล์ใหม่ได้

ดังนั้น หากคุณมีสิทธิ์เข้าถึง phpMyAdmin หรือไคลเอนต์อื่น ๆ บนเครื่องระยะไกล มีความเป็นไปได้สูงที่คุณจะสามารถเข้าถึงระบบไฟล์ผ่าน MySQL แต่เฉพาะในกรณีที่ตั้งค่าแฟล็ก FILE_PRIV=yes ในการตั้งค่า daemon ซึ่งไม่ได้เป็นเช่นนั้นเสมอไป ในกรณีนี้ เราต้องจำเกี่ยวกับโอเปอเรเตอร์อื่นซึ่งไม่ค่อยมีใครรู้จักมากนัก แต่ในขณะเดียวกันก็มีฟังก์ชันที่ค่อนข้างทรงพลัง ฉันกำลังพูดถึงตัวดำเนินการโหลดข้อมูล INFILE ซึ่งจะกล่าวถึงคุณสมบัติต่างๆ ในบทความนี้

ปฏิสัมพันธ์ระหว่าง PHP และ MySQL

PHP เป็นภาษาที่ใช้กันทั่วไปในการสร้างเว็บแอปพลิเคชัน ดังนั้นจึงควรพิจารณาอย่างใกล้ชิดว่า PHP โต้ตอบกับฐานข้อมูลอย่างไร

ใน PHP4 ไลบรารีไคลเอนต์ MySQL ถูกรวมไว้ตามค่าเริ่มต้นและรวมอยู่ในการกระจาย PHP ดังนั้นระหว่างการติดตั้งคุณสามารถเลือกไม่ใช้ MySQL ได้โดยการระบุตัวเลือกเท่านั้น

โดยไม่ต้อง-mysql

PHP5 มาโดยไม่มีไลบรารีไคลเอนต์ บนระบบ *nix โดยปกติแล้ว PHP5 จะถูกคอมไพล์ด้วยไลบรารี libmysqlclient ที่ติดตั้งไว้แล้วบนเซิร์ฟเวอร์ เพียงแค่ตั้งค่าตัวเลือก

ด้วย-mysql=/usr

ระหว่างการประกอบ อย่างไรก็ตาม จนถึงเวอร์ชัน 5.3 นั้น MySQL Client Library ระดับต่ำ (libmysql) ใช้เพื่อโต้ตอบกับเซิร์ฟเวอร์ MySQL ซึ่งเป็นอินเทอร์เฟซที่ไม่ได้รับการปรับให้เหมาะสมสำหรับการสื่อสารกับแอปพลิเคชัน PHP

สำหรับเวอร์ชันของ PHP 5.3 และสูงกว่านั้น MySQL Native Driver (mysqlnd) ได้รับการพัฒนา และในเวอร์ชันล่าสุดของ PHP 5.4 ไดรเวอร์นี้จะถูกใช้เป็นค่าเริ่มต้น แม้ว่าไดรเวอร์ MySQL ในตัวจะถูกเขียนเป็นส่วนขยายของ PHP แต่สิ่งสำคัญคือต้องเข้าใจว่าไดรเวอร์ดังกล่าวไม่มี API ใหม่ให้กับโปรแกรมเมอร์ PHP API ฐานข้อมูล MySQL สำหรับโปรแกรมเมอร์มีให้โดยส่วนขยาย MySQL, mysqli และ PDO_MYSQL ส่วนขยายเหล่านี้สามารถใช้ไดรเวอร์ MySQL ในตัวเพื่อสื่อสารกับ MySQL daemon

การใช้ไดรเวอร์ MySQL ในตัวมีข้อดีบางประการเหนือไลบรารีไคลเอ็นต์ MySQL ตัวอย่างเช่น คุณไม่จำเป็นต้องติดตั้ง MySQL เพื่อสร้าง PHP หรือใช้สคริปต์ฐานข้อมูล ข้อมูลเพิ่มเติมเกี่ยวกับ MySQL Native Driver และความแตกต่างจาก libmysql มีอยู่ในเอกสารประกอบ

ส่วนขยาย MySQL, mysqli และ PDO_MYSQL สามารถกำหนดค่าแยกกันเพื่อใช้ libmysql หรือ mysqlnd ได้ ตัวอย่างเช่น ในการกำหนดค่าส่วนขยาย MySQL เพื่อใช้ไลบรารีไคลเอ็นต์ MySQL และส่วนขยาย mysqli เพื่อทำงานกับ MySQL Native Driver คุณต้องระบุตัวเลือกต่อไปนี้:

`./configure --with-mysql=/usr/bin/mysql_config --with-mysqli=mysqlnd`

โหลดข้อมูลไวยากรณ์

คำสั่ง LOAD DATA ตามที่เอกสารระบุไว้ จะอ่านแถวจากไฟล์และโหลดลงในตารางด้วยความเร็วสูงมาก ใช้ได้กับ คำสำคัญ LOCAL (พร้อมใช้งานใน MySQL 3.22.6 และใหม่กว่า) ซึ่งระบุตำแหน่งที่จะโหลดข้อมูล หากไม่มีคำว่า LOCAL แสดงว่าเซิร์ฟเวอร์โหลดไฟล์ที่ระบุลงในตารางจากเครื่องท้องถิ่น ไม่ใช่จากเครื่องไคลเอ็นต์ นั่นคือไฟล์จะไม่ถูกอ่านโดยไคลเอนต์ MySQL แต่โดยเซิร์ฟเวอร์ MySQL แต่การดำเนินการนี้อีกครั้งต้องใช้สิทธิ์ FILE (FILE_PRIV=yes flag) การดำเนินการคำสั่งในกรณีนี้สามารถเปรียบเทียบได้กับการใช้ฟังก์ชัน LOAD_FILE โดยมีข้อแตกต่างเพียงอย่างเดียวคือข้อมูลจะถูกโหลดลงในตารางแทนที่จะเป็นเอาต์พุต ดังนั้น การใช้ LOAD DATA INFILE เพื่ออ่านไฟล์จะเหมาะสมก็ต่อเมื่อฟังก์ชัน LOAD_FILE ไม่พร้อมใช้งาน นั่นคือบนเซิร์ฟเวอร์ MySQL เวอร์ชันเก่ามาก

แต่ถ้าใช้โอเปอเรเตอร์ในรูปแบบนี้: LOAD DATA LOCAL INFILE นั่นคือโดยใช้คำว่า LOCAL ไฟล์นั้นจะถูกอ่านโดยโปรแกรมไคลเอนต์ (บนเครื่องไคลเอนต์) และส่งไปยังเซิร์ฟเวอร์ที่มีฐานข้อมูลอยู่ ในกรณีนี้ ไม่จำเป็นต้องใช้สิทธิ์ FILE ในการเข้าถึงไฟล์ (เนื่องจากทุกอย่างเกิดขึ้นบนเครื่องของลูกค้า)

ส่วนขยาย MySQL/mysqli/PDO_MySQL และคำสั่ง LOAD DATA LOCAL

ในส่วนขยาย MySQL ความสามารถในการใช้ LOCAL จะถูกควบคุมโดยคำสั่ง PHP_INI_SYSTEM mysql.allow_local_infile ตามค่าเริ่มต้น คำสั่งนี้มีค่าเป็น 1 ดังนั้นตัวดำเนินการที่เราต้องการจึงมักจะพร้อมใช้งาน นอกจากนี้ ฟังก์ชัน mysql_connect ยังช่วยให้คุณเปิดใช้งานความสามารถในการใช้ LOAD DATA LOCAL หากอาร์กิวเมนต์ที่ห้ามีค่าคงที่ 128

เมื่อใช้ส่วนขยาย PDO_MySQL เพื่อเชื่อมต่อกับฐานข้อมูล เรายังสามารถเปิดใช้งานการสนับสนุน LOCAL โดยใช้ค่าคงที่ PDO::MYSQL_ATTR_LOCAL_INFILE (จำนวนเต็ม)

$pdo = new PDO("mysql:host=localhost;dbname=mydb", "user", "pass", array(PDO::MYSQL_ATTR_LOCAL_INFILE => 1));

แต่โอกาสที่ยิ่งใหญ่ที่สุดในการทำงานกับตัวดำเนินการ LOAD DATA นั้นมาจากส่วนขยาย mysqli ส่วนขยายนี้ยังจัดเตรียมคำสั่ง PHP_INI_SYSTEM mysqli.allow_local_infile ซึ่งควบคุมการใช้ LOCAL

หากทำการเชื่อมต่อผ่าน mysqli_real_connect จากนั้นใช้ mysqli_options เราสามารถเปิดและปิดการสนับสนุน LOCAL ได้ นอกจากนี้ ฟังก์ชัน mysqli_set_local_infile_handler ยังมีอยู่ในส่วนขยายนี้ ซึ่งช่วยให้คุณสามารถลงทะเบียนฟังก์ชันเรียกกลับเพื่อจัดการเนื้อหาของไฟล์ที่อ่านโดยคำสั่ง LOAD DATA LOCAL INFILE

กำลังอ่านไฟล์

ผู้อ่านที่ใส่ใจอาจเดาได้แล้วว่าหากเรามีบัญชีใน phpMyAdmin เราก็สามารถอ่านไฟล์ที่ต้องการได้โดยไม่ต้องมีสิทธิ์ FILE และแม้แต่ข้ามข้อ จำกัด open_basedir ท้ายที่สุดบ่อยครั้งทั้งไคลเอนต์ (ในกรณีนี้คือ phpMyAdmin) และ MySQL daemon อยู่บนเครื่องเดียวกัน แม้จะมีข้อจำกัดของนโยบายความปลอดภัยของเซิร์ฟเวอร์ MySQL แต่เราสามารถใช้ประโยชน์จากข้อเท็จจริงที่ว่านโยบายนี้ใช้ไม่ได้กับไคลเอนต์และยังคงอ่านไฟล์จากระบบโดยการพุชไฟล์เหล่านั้นลงในฐานข้อมูล

อัลกอริธึมนั้นง่าย การรันคำสั่ง SQL ต่อไปนี้ก็เพียงพอแล้ว:

  1. เราสร้างตารางที่เราจะบันทึกเนื้อหาของไฟล์: CREATE TABLE temp(ข้อความเนื้อหา);
  2. เราส่งเนื้อหาของไฟล์ไปยังตารางที่สร้างขึ้น: LOAD DATA LOCAL INFILE "/etc/hosts" ลงในตาราง temp FIELDS TERMINATED BY "eof" ESCAPED BY "" LINES TERMINATED BY "eof";

เอาล่ะ ขณะนี้เนื้อหาของไฟล์ /etc/hosts อยู่ในตารางชั่วคราว ต้องการอ่านไฟล์ไบนารี่หรือไม่? ไม่มีปัญหา. หากในขั้นตอนแรกเราสร้างตารางดังนี้:

สร้างตาราง "bin" ("bin" BLOB ไม่เป็นโมฆะ) ENGINE = MYISAM;

จากนั้นจะสามารถโหลดไฟล์ไบนารี่ลงไปได้ จริงอยู่ จะมีการเพิ่มบิตพิเศษที่ส่วนท้ายของไฟล์ แต่สามารถลบออกได้ในโปรแกรมแก้ไข hex ใดก็ได้ วิธีนี้ทำให้คุณสามารถดาวน์โหลดสคริปต์ที่ป้องกันโดย IonCube/Zend/TrueCrypt/NuSphere จากเซิร์ฟเวอร์และถอดรหัสได้

อีกตัวอย่างหนึ่งของวิธีที่คุณสามารถใช้ LOAD DATA LOCAL INFILE คือการค้นหาเส้นทางไปยังการกำหนดค่า Apache ทำได้ดังนี้:

  1. ขั้นแรก เราจะหาเส้นทางไปยังไบนารี่ โดยอ่าน /proc/self/cmdline โดยใช้วิธีที่อธิบายไว้ข้างต้น
  2. จากนั้นเราจะอ่านไบนารี่โดยตรง โดยที่เรามองหา HTTPD_ROOT/SERVER_CONFIG_FILE


เป็นที่ชัดเจนว่าในสถานการณ์นี้สคริปต์ phpMyAdmin มีบทบาทเป็นไคลเอ็นต์ในการเชื่อมต่อกับฐานข้อมูล และแทนที่จะใช้ phpMyAdmin คุณสามารถใช้เว็บอินเตอร์เฟสอื่นเพื่อทำงานกับ MySQL ได้

ตัวอย่างเช่น คุณสามารถใช้สคริปต์เพื่อสำรองและกู้คืนฐานข้อมูลได้ ย้อนกลับไปในปี 2550 แฮ็กเกอร์ชาวฝรั่งเศสภายใต้ชื่อเล่นว่า acidroot ได้เผยแพร่ช่องโหว่ตามความคิดเห็นนี้ และทำให้สามารถอ่านไฟล์จากแผงผู้ดูแลระบบ phpBB<= 2.0.22.

อุโมงค์ก็สะดวก อุโมงค์ไม่ปลอดภัย

เมื่อติดตั้งเว็บแอปพลิเคชันที่ซับซ้อน มักจำเป็นต้องเข้าถึงฐานข้อมูลโดยตรง เช่น เพื่อการกำหนดค่าเริ่มต้นและการปรับเปลี่ยนสคริปต์ ดังนั้นในบางกรณี ขอแนะนำให้ติดตั้งสคริปต์ง่ายๆ บนเซิร์ฟเวอร์ - ที่เรียกว่า MySQL Tunnel ซึ่งช่วยให้คุณสามารถดำเนินการสืบค้นฐานข้อมูลโดยใช้ไคลเอนต์ที่สะดวกแทน phpMyAdmin ที่ใช้งานหนัก

มีอุโมงค์จำนวนหนึ่งสำหรับการทำงานกับฐานข้อมูล แต่ทั้งหมดนั้นไม่ธรรมดานัก บางทีหนึ่งในสคริปต์ที่มีชื่อเสียงที่สุดคือ Macromedia Dream Weaver Server Scripts คุณสามารถดูซอร์สโค้ดของสคริปต์นี้ได้

ข้อแตกต่างที่สำคัญระหว่าง MySQL Tunnel และ phpMyAdmin คือความจำเป็นในการป้อนข้อมูลไม่เพียง แต่การเข้าสู่ระบบและรหัสผ่านสำหรับฐานข้อมูล แต่ยังรวมถึงโฮสต์ที่จะเชื่อมต่อด้วย ในเวลาเดียวกัน อุโมงค์มักจะเปิดทิ้งไว้ เผื่อในกรณีที่คุณไม่มีทางรู้ว่าจะต้องปรับเปลี่ยนอะไรอีก ดูเหมือนว่าคุณสามารถใช้มันได้ก็ต่อเมื่อคุณมีบัญชีอยู่ในฐานข้อมูล แล้วทำไมต้องกลัวล่ะ? กล่าวโดยสรุป ดูเหมือนว่าทันเนลจะไม่ก่อให้เกิดภัยคุกคามด้านความปลอดภัยต่อเว็บเซิร์ฟเวอร์โดยเฉพาะ แต่ในความเป็นจริงไม่ใช่ทุกอย่างจะดีเท่าที่เห็นในครั้งแรก

พิจารณาสถานการณ์ต่อไปนี้ ให้เซิร์ฟเวอร์ A มีเว็บไซต์ site.com พร้อมด้วยอุโมงค์ที่สร้างขึ้น http://site.com/_mmServerScripts/MMHTTPDB.php สมมติว่าบนเซิร์ฟเวอร์ A คุณสามารถใช้ LOAD DATA LOCAL ได้ (ดังที่กล่าวไว้ข้างต้น ซึ่งสามารถทำได้โดยใช้การตั้งค่าเริ่มต้น) ในกรณีนี้ เราสามารถใช้เซิร์ฟเวอร์ MySQL ระยะไกล ซึ่งสามารถเข้าถึงฐานข้อมูลได้จากทุกที่และยังอนุญาตให้ใช้ LOCAL และเชื่อมต่อกับเซิร์ฟเวอร์นี้โดยใช้ทันเนล ข้อมูลสำหรับการเชื่อมต่อกับเซิร์ฟเวอร์ MySQL ระยะไกล:

โฮสต์ DB: xx.xx.xx.xxx ชื่อ DB: name_remote_db ผู้ใช้ DB: our_user DB Pass: our_pass

ในสถานการณ์นี้ เซิร์ฟเวอร์ A จะมีบทบาทเป็นไคลเอ็นต์ ดังนั้นเราจึงสามารถส่งไฟล์จากโฮสต์ไปยังฐานข้อมูลระยะไกล หรืออีกนัยหนึ่งคือ อ่านไฟล์ได้ ด้วยคำถามง่ายๆ ดังนี้

Type=MYSQL&Timeout=100&Host=xx.xx.xx.xxx&Database=name_remote_db&UserName=our_user&Password=our_pass&opCode=ExecuteSQL&SQL=LOAD DATA LOCAL INFILE /path/to/script/setup_options.php" ลงในตาราง tmp_tbl FIELDS TERMINATED BY "__eof__" ESCAP ED BY " " เส้นสิ้นสุดโดย "__eof__"

ในความเป็นจริง ช่องโหว่นี้มีอันตรายมากกว่าการอ่านไฟล์ทั่วไป เพราะจะช่วยให้คุณสามารถอ่านไฟล์การกำหนดค่าของสคริปต์ที่ติดตั้งบนเซิร์ฟเวอร์ A ได้ คุณสามารถเข้าถึงฐานข้อมูลที่จัดการสคริปต์เหล่านี้ได้โดยตรงผ่านช่องทางเดียวกัน เทคนิคที่อธิบายไว้ข้างต้นสำหรับการใช้อุโมงค์กล้ามเนื้อสามารถสรุปได้เล็กน้อยและนำไปใช้เมื่อใช้ประโยชน์จากช่องโหว่ที่ไม่เป็นอนุกรม


ไคลเอนต์เซิร์ฟเวอร์

เพื่อให้เข้าใจถึงความสามารถของ LOAD DATA ได้ดียิ่งขึ้น จำเป็นต้องจำไว้ว่า MySQL DBMS ใช้สถาปัตยกรรมไคลเอ็นต์-เซิร์ฟเวอร์แบบดั้งเดิม เมื่อทำงานกับ MySQL เราทำงานร่วมกับสองโปรแกรมจริงๆ:

  • โปรแกรมเซิร์ฟเวอร์ฐานข้อมูลที่อยู่บนคอมพิวเตอร์ที่เก็บฐานข้อมูล mysqld daemon จะรับฟังคำขอของไคลเอ็นต์ผ่านเครือข่ายและเข้าถึงเนื้อหาของฐานข้อมูล โดยให้ข้อมูลที่ไคลเอ็นต์ร้องขอ หาก mysqld เริ่มต้นด้วยตัวเลือก --local-infile=0 แสดงว่า LOCAL จะไม่ทำงาน
  • โปรแกรมไคลเอนต์เชื่อมต่อกับเซิร์ฟเวอร์และส่งคำขอไปยังเซิร์ฟเวอร์ การแจกจ่าย MySQL DBMS ประกอบด้วยโปรแกรมไคลเอ็นต์หลายโปรแกรม: คอนโซลไคลเอ็นต์ MySQL (ที่ใช้กันมากที่สุด) เช่นเดียวกับ mysqldump, mysqladmin, mysqlshow, mysqlimport และอื่นๆ และหากจำเป็น คุณสามารถสร้างโปรแกรมไคลเอนต์ของคุณเองโดยใช้ไลบรารีไคลเอนต์ libmysql มาตรฐาน ซึ่งมาพร้อมกับ MySQL DBMS

หากคุณไม่สามารถใช้คำสั่ง LOAD DATA LOCAL เมื่อใช้ไคลเอนต์ MySQL มาตรฐาน คุณควรใช้สวิตช์ --local-infile:

Mysql --local-infile sampdb mysql> โหลดข้อมูลภายใน INFILE "member.txt" ลงในสมาชิกตาราง;

หรือระบุตัวเลือกสำหรับไคลเอ็นต์ในไฟล์ /my.cnf:

Local-infile=1

สิ่งสำคัญที่ควรทราบคือโดยค่าเริ่มต้น ไคลเอนต์และไลบรารี MySQL ทั้งหมดจะถูกคอมไพล์ด้วยตัวเลือก --enable-local-infile เพื่อให้แน่ใจว่าเข้ากันได้กับ MySQL 3.23.48 และเวอร์ชันเก่ากว่า ดังนั้น LOAD DATA LOCAL มักจะพร้อมใช้งานสำหรับไคลเอนต์มาตรฐาน อย่างไรก็ตาม คำสั่งไปยังเซิร์ฟเวอร์ MySQL ส่วนใหญ่ไม่ได้ส่งมาจากคอนโซล แต่ส่งจากสคริปต์ ดังนั้นภาษาการพัฒนาเว็บจึงมีไคลเอ็นต์สำหรับการทำงานกับฐานข้อมูลด้วย ซึ่งอาจแตกต่างจากฟังก์ชันการทำงานจากไคลเอนต์ MySQL มาตรฐาน

แน่นอนว่าคุณลักษณะนี้ของคำสั่ง LOAD DATA อาจเป็นภัยคุกคามต่อความปลอดภัยของระบบ ดังนั้นตั้งแต่ MySQL 3.23.49 และ MySQL 4.0.2 (4.0.13 สำหรับ Win) ตัวเลือก LOCAL จะใช้งานได้ก็ต่อเมื่อทั้งไคลเอนต์ และเซิร์ฟเวอร์เปิดใช้งานได้

ข้ามข้อจำกัด open_basedir

การใช้ LOAD DATA ค่อนข้างบ่อยทำให้คุณสามารถข้ามข้อจำกัดของ open_basedir ได้ สิ่งนี้อาจมีประโยชน์ ตัวอย่างเช่น หากเราสามารถเข้าถึงไดเร็กทอรีของผู้ใช้รายหนึ่งบนโฮสติ้งที่ใช้ร่วมกัน แต่ต้องการอ่านสคริปต์จากโฮมไดเร็กตอรี่ของผู้ใช้รายอื่น จากนั้นทำการติดตั้งสคริปต์นี้

1)); $e=$pdo->exec("LOAD DATA LOCAL INFILE "./path/to/file" INTO TABLE test FIELDS TERMINATED BY "__eof__" ESCAPED BY "" LINES TERMINATED BY "__eof__""); $pdo = โมฆะ; ?>

บทสรุป

เป็นที่น่าสนใจที่ความสามารถที่อธิบายไว้ของผู้ปฏิบัติงาน LOAD DATA นั้นเป็นที่รู้จักมาเป็นเวลาอย่างน้อยสิบปี ตัวอย่างเช่น สามารถพบการกล่าวถึงได้ในตั๋ว [#15408] (Safe Mode / MySQL Vuln 2002-02-06) จากนั้นคำถามที่คล้ายกันก็ปรากฏขึ้นซ้ำแล้วซ้ำอีกใน bugs.php.net [#21356] [#23779 ] [#28632 ] [#31261] [#31711]. ซึ่งนักพัฒนาก็ตอบคำต่อคำต่อไปนี้:

[ป้องกันอีเมล]ไม่ใช่จุดบกพร่อง แต่เป็นคุณลักษณะ :)

หรือพวกเขามอบหมายตั๋ว "สถานะ: จะไม่แก้ไข" หรือจำกัดอยู่แค่แพตช์ที่แทบแก้ไขอะไรไม่ได้เลย ตั๋วในหัวข้อนี้เกิดขึ้นอีกครั้ง ดังนั้นวิธีการข้าม open_basedir ที่ระบุยังคงใช้งานได้บนเซิร์ฟเวอร์จำนวนมาก อย่างไรก็ตาม ด้วยการถือกำเนิดของไดรเวอร์ mysqlnd ใหม่ ดูเหมือนว่ามีการตัดสินใจทำการเปลี่ยนแปลงที่สำคัญ: ด้วยการติดตั้งเริ่มต้น โอเปอเรเตอร์นี้จะไม่ถูกดำเนินการเลย [#54158] [#55737] หวังว่าในอนาคตอันใกล้นี้นักพัฒนาจะจัดระเบียบในเรื่องนี้