A seguito del frammento collegati da Pickett, ho fatto un paio di modifiche per:
1) Aggiornare a utilizzare il nuovo Query Builder (CI 3), precedentemente conosciuto come Active Record.
2) Si può ora passare un array associativo (chiave => valore) o un array di array associativi. Nel secondo modulo, esegue un multi-aggiornamento.
L'ho provato solo con mysqli e funziona bene.
Questo pezzo di codice va nel sistema/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;
}
E questo va nel file /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);
}
allora si può fare questo per un singolo inserto riga/aggiornamento:
$this->db->on_duplicate('table', array('column1' => 'value', 'column2' => 'value'));
O questo per un multi inserto/aggiornamento:
$this->db->on_duplicate('table', array(
array('column1' => 'value', 'column2' => 'value'),
array('column1' => 'value', 'column2' => 'value')
));
sì ha aiutato :) – Nishant
Questa è la soluzione più pulita finché CI non aggiunge questo. Vota su/ – Nemke
Che è dubbio perché lasciano il supporto :(http://ellislab.com/blog/entry/ellislab-seeking-new-owner-for-codeigniter – Shaffe