import sql ด้วย codeigniter

การ import sql ผ่านทางหน้าเว็บ โดยไม่ใช้ phpmyadmin ทำได้ไม่ง่าย หลายๆกระทู้ที่มีการถามตอบกันนั้นก็มักจะตอบกันอย่างง่ายๆว่า ใช้คำสั่ง sql import ไฟล์เอาได้เลย แต่ถ้าเป็นผู้ใช้ shared host ก็คงหมดสิทธิ์.
ถึงจะอย่างนั้นมันก็ยังมีวิธีทำได้อยู่ เพียงแต่มีข้อจำกัดเกี่ยวกับทรัพยากรของ server ที่จะให้เราได้ใช้ว่าจะพอหรือไม่ก็เท่านั้น

หลักการทำงาน

อัพโหลดไฟล์ .sql ขึ้นไปบน server ถ้าอัพเป็น .zip, .gz ก็ต้องแตกไฟล์ออกด้วยนะครับ
อ่านไฟล์ แล้วเอามาลบ comment sql ต่างๆ เช่น -- table aaaaa หรือ # table bbbbb ลบสิ่งเหล่านี้ออกไปให้หมด
แยกคำสั่งออกจากกันด้วย explode \n
นำค่าที่แยกได้ ซึ่งเป็น array นั้นมาวน foreach เพื่อทำการ query ต่อไป

ข้อจำกัด

จากงานที่เคยทำ พบว่า คำสั่ง sql สองพันกว่าบรรทัด ขนาดไฟล์ปาเข้าไปเกือบ 800 KB
แล้วตอนวน query ทีละคำสั่ง เกือบจะมีอาการ memory ไม่พอกับที่ limit ไว้ (อยากรู้ว่าสวาปามเมโมรี่ไปเท่าไหร่ให้ใช้คำสั่ง memory_get_peak_usage() ดูนะครับ)
ดังนั้นก่อนทำการวน query ทีละคำสั่งนั้น ขอให้เช็คขนาดไฟล์เสียก่อน พยายามอย่าให้เกิน 700 KB ดีที่สุด และถ้าเกินคงต้องไปใช้ phpmyadmin แทนแล้วครับ

ตัวอย่าง


if ( isset($_FILES['file']['name']) ) {
    $this->load->library('upload');
    $config['upload_path'] = dirname(BASEPATH);// ตำแหน่งนี้คือ root ของเว็บนั่นเอง
    $config['allowed_types'] = "sql";
    $this->upload->initialize($config);
    if ( ! $this->upload->do_upload("file") ) {
        echo "fail to upload";
    } else {
        $data = $this->upload->data();
        $sql_path = $data['full_path'];
        $sql_file = $this->load->file($sql_path, true);
        $sql_file = preg_replace("/^\#(.*)\n$/", "", $sql_file);// ลบพวก comment ใน sql แบบ # table xxxx ออก
        $asql = explode("\n", $sql_file);
        foreach ( $asql as $key ) {
            if ( trim($key) != null ) {
                $this->db->query(trim($key));
                if ( $i >= 1000 ) {
                    sleep(3);
                    $i = 0;
                }
                $i++;
            }
        }// end foreach
    }
}


ตัวอย่างการทำงานใน controller นะครับ
$sql_file = preg_replace("/^\#(.*)\n$/", "", $sql_file); คือลบ comment แบบ # ออก ซึ่งมักมีอยู่ใน sql ที่ถูก export จาก phpmyadmin รุ่นเก่าๆ
ถ้าเป็น comment sql ในรุ่นใหม่ๆจะเป็นแบบ -- table aaaa แบบนี้ ก็ใช้คำสั่งข้างล่างนี้
$sql_file = preg_replace("/^--(.*)\n$/", "", $sql_file);

ในการวน foreach ก็น่าจะมีการนับจำนวนผ่านตัวแปร $i ไปด้วย ถ้ามันเท่ากับ 1000 ครั้ง ก็ให้ระบบหยุดประมวลผลเฉพาะส่วนนี้ 3 วินาที จะได้เบาการทำงานลง ดีกว่าอัดๆกันเข้าไปทีเดียว

เสร็จแล้วก็อย่าลืม unlink ไฟล์ .sql ที่อัพโหลดขึ้นไป แล้วก็ตรวจสอบผลการทำงาน ซึ่งถ้าไม่มี error ในขั้นตอนข้างบนนี้ก็ถือว่าประสบความสำเร็จ.

ใส่ความเห็น

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *

คุณอาจใช้แท็กHTMLและแอททริบิวต์เหล่านี้: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>