Siguiendo el fragmento unido por Pickett, hice algunas modificaciones a:
1) Actualizar a utilizar el nuevo generador de consultas (IC 3), anteriormente conocida como Active Record.
2) Ahora puede pasar una matriz asociativa (clave => valor) o una matriz de matrices asociativas. En la segunda forma, realiza una actualización múltiple.
Solo lo probé con mysqli, y funciona bien.
Este fragmento de código va en system/database/drivers/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;
}
Y esto va en el archivo /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);
}
entonces usted puede hacer esto por una sola fila de inserción/actualización:
$this->db->on_duplicate('table', array('column1' => 'value', 'column2' => 'value'));
O esto para una inserción múltiple/actualización:
$this->db->on_duplicate('table', array(
array('column1' => 'value', 'column2' => 'value'),
array('column1' => 'value', 'column2' => 'value')
));
sí, ayudó :) – Nishant
Esta es la solución más limpia hasta que CI no lo agregue. Votar arriba 0/ – Nemke
Lo cual es dudoso porque dejan de admitir :(http://ellislab.com/blog/entry/ellislab-seeking-new-owner-for-codeigniter – Shaffe