手始めに、update_batchに関するCodeigniterのドキュメントは存在しません。 kenjisは親切にもいくつかのドキュメントを提供し、それをリポジトリに提出してくれました。うまくいけば、彼らはすぐにそれを引っ張る。
Codeigniters update_batchコマンドに複数のwhere条件を追加する方法を知っている人はいますか?
私の希望する用途:
$where = array(
'title',
'name'
);
$this->db->update_batch('mytable', $data, $where);
このコードを試したところ、次のエラーが発生しました。
A Database Error Occurred
One or more rows submitted for batch updating is missing the specified index.
Filename: C:\wamp\www\wheel\system\database\DB_active_rec.php
Line Number: 1451
kenjisによるバッチドキュメントの更新:
$this->db->update_batch();
指定したデータに基づいて更新文字列を生成し、クエリを実行します。 arrayまたはobjectを関数に渡すことができます。配列を使用した例を次に示します。
$data = array(
array(
'title' => 'My title' ,
'name' => 'My Name 2' ,
'date' => 'My date 2'
),
array(
'title' => 'Another title' ,
'name' => 'Another Name 2' ,
'date' => 'Another date 2'
)
);
$this->db->update_batch('mytable', $data, 'title');
// Produces:
// UPDATE `mytable` SET `name` = CASE
// WHEN `title` = 'My title' THEN 'My Name 2'
// WHEN `title` = 'Another title' THEN 'Another Name 2'
// ELSE `name` END,
// `date` = CASE
// WHEN `title` = 'My title' THEN 'My date 2'
// WHEN `title` = 'Another title' THEN 'Another date 2'
// ELSE `date` END
// WHERE `title` IN ('My title','Another title')
最初のパラメーターにはテーブル名が含まれ、2番目のパラメーターは値の連想配列であり、3番目のパラメーターはwhereキーです。
update_batch()
に複数のwhere句を追加することはできません。 where句の3番目のパラメーターとして文字列のみを受け入れるため、メソッドが現在記述されている方法でこれを行う方法はないと確信しています。
ソース から:
/**
* Update_Batch
*
* Compiles an update string and runs the query
*
* @param string the table to retrieve the results from
* @param array an associative array of update values
* @param string the where key
* @return object
*/
public function update_batch($table = '', $set = NULL, $index = NULL)
Codeigniter 3.1.5を使用していて同じ問題が発生しましたが、次のように問題を解決しました。
$data = array(
array(
'title' => 'My title' ,
'name' => 'My Name 2' ,
'date' => 'My date 2'
),
array(
'title' => 'Another title' ,
'name' => 'Another Name 2' ,
'date' => 'Another date 2'
)
);
$this->db->where('name','My Name 2');
$this->db->update_batch('mytable', $data, 'title');
それを生成します:
// Produces:
// UPDATE `mytable`
// SET `name` = CASE
// WHEN `title` = 'Another title' THEN 'Another Name 2'
// WHEN `title` = 'My title' THEN 'My Name 2'
// ELSE `name`
// END,
// `date` = CASE
// WHEN `title` = 'My title' THEN 'My date 2'
// WHEN `title` = 'Another title' THEN 'Another date 2'
// ELSE `date`
// END
// WHERE `title` IN ('My title','Another title')
// AND `name` = 'My Name 2'
更新
たとえば、update_batchを使用して100を超えるレコードを追加しようとすると問題が発生しました。
$data = [1=>a,2=>b ... 200=>zz];
最初の呼び出し(WHEREを使用):
// Produces:
// UPDATE `mytable`
// SET `name` = CASE
// WHEN `title` = 'My title' THEN 'My Name 2'
// WHEN `title` = 'Another title' THEN 'Another Name 2'
// ELSE `name`
// END,
// `date` = CASE
// WHEN `title` = 'My title' THEN 'My date 2'
// WHEN `title` = 'Another title' THEN 'Another date 2'
// ELSE `date`
// END
// WHERE `title` IN ('My title','Another title')
// AND `name` = 'My Name 2'
2回目の呼び出し(WHEREなし):
// Produces:
// UPDATE `mytable`
// SET `name` = CASE
// WHEN `title` = 'My title' THEN 'My Name 2'
// WHEN `title` = 'Another title' THEN 'Another Name 2'
// ELSE `name`
// END,
// `date` = CASE
// WHEN `title` = 'My title' THEN 'My date 2'
// WHEN `title` = 'Another title' THEN 'Another date 2'
// ELSE `date`
// END
// WHERE `title` IN ('My title','Another title')
これを試して:
$chunk1 = array_chunk($data,100);
for($i=0;$i < count($chunk1);$i++) {
$this->upload_model->update_data($chunk1[$i],'My Name 2');
}
モデル:
public function update_data($data='',$name=''){
$this->db->where('name',$name);
$this->db->update_batch('mytable', $data, 'title');
}
WHEREクエリがバッチループでクリアされているため、_update_batch
_で複数のwhere条件が壊れています。
バッチ更新ループは次のとおりです。
_ for ($i = 0, $total = count($this->qb_set_ub); $i < $total; $i += $batch_size)
{
if ($this->query($this->_update_batch($this->protect_identifiers($table, TRUE, NULL, FALSE), array_slice($this->qb_set_ub, $i, $batch_size), $index)))
{
$affected_rows += $this->affected_rows();
}
$this->qb_where = array();
}
_
渡されたWHERE条件が$this->qb_where = array();
によってクリアされることに注意してください。
CodeIgniter v3.1.10では、問題のある行は1940年の_DB_query_builder.php
_にあります。これにより、WHERE条件が処理された最初のバッチ(デフォルトは100)で機能し、後続のバッチで失敗するという非常に予期しない動作が発生します。
2つの可能な解決策があります:
batch_size
_の4番目の_update_batch
_パラメーターを使用し、100,000などの大きな数値を渡すと、すべてのクエリが最初のバッチで処理され、WHERE条件がクリアされません。ソリューション#2のコード:
_ // Save initial where conditions.
$where_holder = $this->qb_where;
// Batch this baby
$affected_rows = 0;
for ($i = 0, $total = count($this->qb_set_ub); $i < $total; $i += $batch_size)
{
if ($this->query($this->_update_batch($this->protect_identifiers($table, TRUE, NULL, FALSE), array_slice($this->qb_set_ub, $i, $batch_size), $index)))
{
$affected_rows += $this->affected_rows();
}
// Restore intial where conditions.
$this->qb_where = $where_holder;
}
_
これがお役に立てば幸いです。