Codeigniter - 具有多个Where条件的批量更新

时间:2011-09-15 05:05:11

标签: codeigniter activerecord codeigniter-2

首先,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();

根据您提供的数据生成更新字符串,然后运行查询。您可以将数组对象传递给该函数。以下是使用数组的示例:

$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')

第一个参数将包含表名,第二个参数是值的关联数组,第三个参数是where键。

来源:

3 个答案:

答案 0 :(得分:17)

您无法向update_batch()添加多个where子句。它只接受一个字符串作为where子句的第三个参数,所以我确信没有办法按照当前编写方法的方式执行此操作。

来自source

/**
 * 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)

答案 1 :(得分:8)

我正在使用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 `column` = 'My title' THEN 'My Name 2'
// WHEN `column` = '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'
  

更新

我尝试使用update_batch添加超过100条记录时遇到问题,例如:

$data = [1=>a,2=>b ... 200=>zz];

第一次调用(使用WHERE):

// Produces: 
// UPDATE `mytable` SET `name` = CASE
// WHEN `column` = 'My title' THEN 'My Name 2'
// WHEN `column` = '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'

第二次打电话(没有WHERE):

// Produces: 
// UPDATE `mytable` SET `name` = CASE
// WHEN `column` = 'My title' THEN 'My Name 2'
// WHEN `column` = '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');
}

答案 2 :(得分:0)

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();
        }

请注意,$this->qb_where = array();已清除传递的WHERE条件。

在CodeIgniter v3.1.10中,违规行位于DB_query_builder.php中的1940年。这会产生非常意外的行为,其中WHERE条件对于第一个处理的批次有效(默认值为100),而在后续的批次中则失败。

有两种可能的解决方案:

  1. 使用batch_size的第四个update_batch参数并传递一个大数(例如100,000),以便所有查询都在第一批中处理,并且不会清除WHERE条件。
  2. 更新有问题的行以恢复初始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;
        }

希望这对您有帮助!