แต่... อย่าเพิ่งคิดนะครับว่า เราจะยิงข้อมูลเป็นก้อนใหญ่ๆไปเลยทีเดียวได้
เพราะว่ามันก็มี limit ในเรื่องของ placeholder อยู่เหมือนกัน ซึ่งถ้าหากเราส่งข้อมูลก้อนใหญ่เกินไปก็จะได้ error นี้กลับมา
PDOException: SQLSTATE[HY000]: General error: 1390 Prepared statement contains too many placeholders in /var/www/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:77แล้ว placeholder มาจากไหน?
สำหรับ Laravel แล้ว เวลาเราสั่ง
Model::insert($data);
แทนที่ข้อมูลทั้งหมดใน $data
จะถูกแปลงเป็น Query String เพียงประโยคเดียวแต่ในความเป็นจริงแล้ว Query ฺBuilder จะสร้าง Query String ขึ้นมาตัวนึง โดยแทนที่ข้อมูลในส่วนของ
VALUES
ทั้งหมดด้วย ?
หรือ placeholder นั่นเอง (จำนวนของ placeholder จึงเท่ากับจำนวนข้อมูลทั้งหมดใน $data
) ซึ่ง placeholder นี้จะถูกแทนค่าด้วยข้อมูลใน $data
เมื่อทำการ query จริงๆเท่านั้นถ้าเจอ error ข้างต้น วิธีแก้ไขที่ง่ายที่สุด คือ การแบ่งข้อมูลออกเป็นก้อนๆ เพื่อให้มีขนาดที่เล็กลง แล้วใช้การ insert หลายครั้งแทน
นอกจากการ insert แล้ว placeholder นี้ยังถูกใช้สำหรับการ select และ update อีกด้วย
กรณีที่เรามี Query Builder และต้องการแสดง Query String ที่แทนค่า placeholder ด้วย $data เรียบร้อยแล้ว สามารถเข้าไปอ่านวิธีการได้ที่ การแปลง Query Builder ไปเป็น SQL Query String
ข้อมูลเพิ่มเติม สามารถอ่านได้ที่ https://stackoverflow.com/questions/18100782/import-of-50k-records-in-mysql-gives-general-error-1390-prepared-statement-con
No comments:
Post a Comment