LoginSignup
8

More than 5 years have passed since last update.

CodeIgniterでinsert_batchする場合のポイント

Posted at

CodeIgniterはシンプルなフレームワークなので、RailsのActiveRecordのような高度な機能はありませんが、それでもDB操作に便利な機能はちょくちょく存在しています。

配列からINSERT

単純なINSERT文であれば、自分でSQLを組み立てなくても、$this -> db -> insert()とすることで実行可能です。文字データのエスケープも自動実行してくれるので、自分で組み立てるより楽だし安全です(日本語版マニュアル1)。

insert.php
$data = array(
   'title' => 'My title' ,
   'name' => 'My Name' ,
   'date' => 'My date'
);

$this->db->insert('mytable', $data); 

// 生成される SQL 文: INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date')

バルクINSERT

大量のデータをINSERTする場合、逐一INSERTを行ってももちろん動作はするのですが、必要以上に負荷がかかってしまいます(MySQLでの例)。ということで、一気に複数行をINSERTする機能があって、CodeIgniterからも、insert_batch()で呼び出すことができます。

insert_batch.php
$data = array(
   array(
      'title' => 'My title' ,
      'name' => 'My Name' ,
      'date' => 'My date'
   ),
   array(
      'title' => 'Another title' ,
      'name' => 'Another Name' ,
      'date' => 'Another date'
   )
);

$this->db->insert_batch('mytable', $data); 

// 生成される SQL 文: 
// INSERT INTO mytable (title, name, date) VALUES
// ('My title', 'My name', 'My date'), ('Another title', 'Another name', 'Another date')

失敗例

上のSQL文を見てみればわかるかもしれませんが、一括INSERTを行う上では、全部同じだけの列を用意する必要があります。CodeIgniterのマニュアルに明記はされていないのですが、一部のキーが欠けた状態でinsert_batchを行おうとすると、途中にArrayが挟まるなどの不可解なエラーが発生してしまいます。

失敗例
$data = array(
   array(
      'title' => 'My title' ,
      'name' => 'My Name' ,
      'date' => 'My date'
   ),
   array(
      'title' => 'Another title' ,
      'name' => 'Another Name' ,
      // 'date' => 'Another date' 削ってみる
   )
);

$this->db->insert_batch('mytable', $data);
// 実行するとSQL文に「Array」が混入してSQLエラー

対策方法

まとめてINSERTするための配列を用意して、ループで加えていくパターンはよくあると思いますが、テンプレートとして全列を用意しておいた配列を先に作って、そこにコピー、書き込みで各行を構築すると便利です。全部NULLでよければ、テンプレート配列は列一覧からarray_fill_keys()一発で作れます。

実践例
$insert_values = array();
$columns = array('column1', 'column2', /* 後略 */);

// $columnsの中身それぞれをキーとして、値はすべてNULLの配列
$row_template = array_fill_keys($columns, NULL);
foreach($data_array as $data_row){
  //PHPだと配列は代入だけでコピーされる
  $row = $row_template;

  //$rowにいろいろ代入

  $insert_values[] = $row;
}
$this->db->insert_batch('mytable', $insert_values);

脚注


  1. このマニュアルはCodeIgniter 2.0 でのものですが、3.0でも「Active Record」という(大げさな)名前が「Query Builder」に変わった程度で、DB操作自体はほぼ同じままです。 

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8