Codeigniter -使用多个Where条件进行批量更新

6kkfgxo0  于 2022-12-07  发布在  其他
关注(0)|答案(4)|浏览(155)

对于初学者来说,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键。

来源:

wb1gzix0

wb1gzix01#

你不能在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)
slsn1g29

slsn1g292#

我正在使用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'

第二次呼叫(不含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');
}
hrysbysz

hrysbysz3#

update_batch中的多个where条件被破坏,因为批处理循环中正在清除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.使用update_batch的第四个batch_size参数并传递一个较大的数字(如100,000),以便在第一批中处理所有查询,并且不清除WHERE条件。
1.更新违规行以还原初始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;
        }

希望这对你有帮助!

rpppsulh

rpppsulh4#

Try this one also !
Suppon you have import data through csv/excel
then store all record in single array like:

Array
(
    [0] => Array
        (
           
            [price] => 100.00
            [part_no] => PD001
            [brand] => 44
            [special_price] => 90.10

        )

    [1] => Array
        (
            
            [price] => 200.00
            [part_no] => PD002
            [special_price] => 150.00
           
        )

)

Step 2:
Call to model
$model = new CatalogModel();
$result = $model->batchUpdateData($final_array);

function batchUpdateData($array = array()){

  $query = $this->db->table('product');
  $price = array();
  $part_no = array();
  $special = array();
  $brand = array();

  if (!empty($array)) {
   foreach ($array as $key => $value) {
    $price[] = $value['price'];
    $part_no[] = $value['part_no'];
    $special[] = $value['special_price'];
    $brand[] = $value['brand'];

  }
  
    $num = count($part_no);
    $sql ="UPDATE product SET "; 
   
   //  price colum update
     $sql .=" price = CASE ";
     for($i=0; $i < $num; $i++){
     $sql .=" WHEN  part_no = '".$part_no[$i]."' AND brand = '".$brand[$i]."'  THEN '".$price[$i]."' ";

   } 
    $sql .="ELSE price END ,";
    
    // special colum update
    $sql .=" special_price = CASE ";
    for($i=0; $i < $num; $i++){
    $sql .=" WHEN  part_no = '".$part_no[$i]."' AND brand = '".$brand[$i]."'  THEN '".$special[$i]."' ";

   } 
    $sql .="ELSE special_price END";
    

   $sql .=" WHERE part_no IN ('" . implode("','", $part_no) . "') ";

   return $this->db->query($sql);

 }

}

This will product query like:
UPDATE `product` SET `price` = CASE WHEN `part_no` = 'PD001'  and `brand` = '44' THEN '100.00' WHEN `part_no` = 'PD002'  and `brand` = '44' THEN '200.00' ELSE `price` END 
WHERE `part_no` IN('PD001','PD002');

If this helpfull give a thumbs up

相关问题