Tiếp theo đoạn nối với nhau bằng Pickett, tôi thực hiện một vài thay đổi để:
1) Cập nhật nó để sử dụng Query Builder mới (CI 3), trước đây gọi là Active Record.
2) Bây giờ bạn có thể chuyển một mảng kết hợp (key => value) hoặc một mảng các mảng kết hợp. Ở dạng thứ hai, nó thực hiện một bản cập nhật đa.
Tôi chỉ thử nghiệm bằng mysqli và nó hoạt động tốt.
Đoạn mã này nằm trong hệ thống/cơ sở dữ liệu/trình điều khiển/mysqli/mysqli_driver.php
function _duplicate_insert($table, $values)
{
$updatestr = array();
$keystr = array();
$valstr = array();
foreach($values as $key => $val)
{
$updatestr[] = $key." = ".$val;
$keystr[] = $key;
$valstr[] = $val;
}
$sql = "INSERT INTO ".$table." (".implode(', ',$keystr).") ";
$sql .= "VALUES (".implode(', ',$valstr).") ";
$sql .= "ON DUPLICATE KEY UPDATE ".implode(', ',$updatestr);
return $sql;
}
function _multi_duplicate_insert($table, $values)
{
$updatestr = array();
$keystr = array();
$valstr = null;
$entries = array();
$temp = array_keys($values);
$first = $values[$temp[0]];
foreach($first as $key => $val)
{
$updatestr[] = $key." = VALUES(".$key.")";
$keystr[] = $key;
}
foreach($values as $entry)
{
$valstr = array();
foreach($entry as $key => $val)
{
$valstr[] = $val;
}
$entries[] = '('.implode(', ', $valstr).')';
}
$sql = "INSERT INTO ".$table." (".implode(', ',$keystr).") ";
$sql .= "VALUES ".implode(', ',$entries);
$sql .= "ON DUPLICATE KEY UPDATE ".implode(', ',$updatestr);
return $sql;
}
Và điều này đi vào các tập tin /system/database/DB_query_builder.php:
function on_duplicate($table = '', $set = NULL)
{
if (! is_null($set))
{
$this->set($set);
}
if (count($this->qb_set) == 0)
{
if ($this->db_debug)
{
return $this->display_error('db_must_use_set');
}
return FALSE;
}
if ($table == '')
{
if (! isset($this->qb_from[0]))
{
if ($this->db_debug)
{
return $this->display_error('db_must_set_table');
}
return FALSE;
}
$table = $this->qb_from[0];
}
$is_multi = false;
foreach (array_keys($set) as $k => $v) {
if ($k === $v) {
$is_multi = true; //is not assoc
break;
}
}
if($is_multi)
{
$sql = $this->_multi_duplicate_insert($this->protect_identifiers($table, TRUE, NULL, FALSE), $this->qb_set);
}
else
{
$sql = $this->_duplicate_insert($this->protect_identifiers($table, TRUE, NULL, FALSE), $this->qb_set);
}
$this->_reset_write();
return $this->query($sql);
}
Sau đó, bạn có thể làm điều này cho một hàng chèn đơn/cập nhật:
$this->db->on_duplicate('table', array('column1' => 'value', 'column2' => 'value'));
Hoặc điều này cho một chèn/cập nhật đa:
$this->db->on_duplicate('table', array(
array('column1' => 'value', 'column2' => 'value'),
array('column1' => 'value', 'column2' => 'value')
));
có nó đã giúp :) – Nishant
Đây là giải pháp sạch nhất cho đến khi CI không thêm điều này. Bỏ phiếu lên o/ – Nemke
Điều đáng ngờ là vì họ bỏ hỗ trợ: (http://ellislab.com/blog/entry/ellislab-seeking-new-owner-for-codeigniter – Shaffe