【问题标题】:Codeigniter update_batch() with included update of the where keyCodeigniter update_batch() 包含 where 键的更新
【发布时间】:2013-05-28 11:20:09
【问题描述】:

我想用 codeigniters update_batch() 函数更新数据库中的多行。
但是 where 中指定的字段也应该更改。

下面的代码应该清楚了:

$set = array(
  array(
    'token'           => '65787131678754',
    'device'          => 'none',
    'new_token_value' => ''
  ),
  array(
    'token'           => '75798451315464',
    'device'          => 'none',
    'new_token_value' => ''
  )
);

$this->db->update_batch(TBL_NAME, $set, 'token');

token 中指定的令牌应使用device 更新为'none',并且token 本身应设置为空字符串''

update_batch() 函数可以做到这一点吗?


在 sql 中我会写类似的东西

UPDATE TBL_NAME
SET token='', device='none'
WHERE token='65787131678754'

一次更新,但多次更新不可行,所以我想使用update_batch() 函数。

【问题讨论】:

  • 你试过了吗?错误是什么?
  • @tomexsans 我没有尝试,因为我不知道如何定义“new_token_value”。但是我不能在同一个数组中添加 2 次 token,一个是实际令牌值,另一个是新值。
  • 那么更新批次不是问题,问题是如何按照您的意愿更新数据。
  • 那么我应该用纯sql和每个令牌的循环来做吗?但我认为这不是一个好的解决方案。您对如何更新多个条目有更好的想法吗?
  • 看看 codeigniter 事务。

标签: php codeigniter activerecord codeigniter-2


【解决方案1】:

我创建了一个与 codeigniter batch_update() 函数基本相同的辅助函数。
但具有更新索引本身的能力。新值由index_update_key 定义。

function update_batch($db, $table = '', $set = NULL, $index = NULL, $index_update_key = '') {
if ($table === '' || is_null($set) || is_null($index) || !is_array($set)) {
    return FALSE;
}

$sql = 'UPDATE ' . $db->protect_identifiers($table) . ' SET ';

$ids = $when = array();
$cases = '';

//generate the WHEN statements from the set array
foreach ($set as $key => $val) {
    $ids[] = $val[$index];

    foreach (array_keys($val) as $field) {
        if ($field != $index && $field != $index_update_key) {
            $when[$field][] = 'WHEN ' . $db->protect_identifiers($index) 
                            . ' = ' . $db->escape($val[$index]) . ' THEN ' . $db->escape($val[$field]);
        } elseif ($field == $index) {
            //if index should also be updated use the new value specified by index_update_key
            $when[$field][] = 'WHEN ' . $db->protect_identifiers($index) 
                            . ' = ' . $db->escape($val[$index]) . ' THEN ' . $db->escape($val[$index_update_key]);
        }
    }
}

//generate the case statements with the keys and values from the when array
foreach ($when as $k => $v) {
    $cases .= "\n" . $db->protect_identifiers($k) . ' = CASE ' . "\n";
    foreach ($v as $row) {
        $cases .= $row . "\n";
    }

    $cases .= 'ELSE ' . $k . ' END, ';
 }

 $sql .= substr($cases, 0, -2) . "\n"; //remove the comma of the last case
 $sql .= ' WHERE ' . $index . ' IN (' . implode(',', $ids) . ')';

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

现在我可以做以下事情了

$set = array(
  array(
    'token'           => '657871316787544',
    'device'          => 'none',
    'new_token_value' => ''
  ),
  array(
    'token'           => '757984513154644',
    'device'          => 'none',
    'new_token_value' => ''
  )
);

update_batch($this->db, 'table_name', $set, 'token', 'new_token_value');

而sql输出是

UPDATE `b2c` SET 
`token` = CASE 
WHEN `token` = '657871316787544' THEN ''
WHEN `token` = '757984513154644' THEN ''
ELSE token END, 
`device` = CASE 
WHEN `token` = '657871316787544' THEN 'none'
WHEN `token` = '757984513154644' THEN 'none'
ELSE device END
WHERE token IN (657871316787544,757984513154644)

【讨论】:

    【解决方案2】:
    $this->db->where('option1', $option1);<br/>
    $this->db->update_batch('table_name', $data, 'option2');
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多