如何在CodeIgniter模型中使用ON DUPLICATE KEY UPDATE?

Jac*_*ack 20 mysql activerecord model codeigniter

我有一个CodeIgniter/PHP模型,我想将一些数据插入数据库.

但是,我在"原始"SQL查询中设置了这个集合:

ON DUPLICATE KEY UPDATE duplicate=duplicate+1
Run Code Online (Sandbox Code Playgroud)

我正在使用CodeIgniter并将我之前的所有控制器内SQL查询转换为ActiveRecord.有没有办法在基于ActiveRecord的模型中执行此操作?

谢谢!

插口

Sha*_*ffe 52

您可以添加"ON DUPLICATE"语句而无需修改任何核心文件.

$sql = $this->db->insert_string('table', $data) . ' ON DUPLICATE KEY UPDATE duplicate=LAST_INSERT_ID(duplicate)';
$this->db->query($sql);
$id = $this->db->insert_id();
Run Code Online (Sandbox Code Playgroud)

我希望它会帮助别人.

  • 由于这是谷歌上“插入重复键”的最佳结果,因此不扩展此答案来满足那些只希望在重复键上插入并返回重复键上的“id”的人是不明智的。=> 重复键更新重复=LAST_INSERT_ID(重复) (3认同)

小智 6

根据皮克特链接的片段,我做了一些修改:

1) 更新它以使用新的查询生成器 (CI 3),以前称为 Active Record。

2) 您现在可以传递关联数组(键 => 值)或关联数组的数组。在第二种形式中,它执行多重更新。

我只用mysqli测试过,效果很好。

这段代码位于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;
}
Run Code Online (Sandbox Code Playgroud)

这进入 /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);
}
Run Code Online (Sandbox Code Playgroud)

然后您可以对单行插入/更新执行此操作:

$this->db->on_duplicate('table', array('column1' => 'value', 'column2' => 'value'));
Run Code Online (Sandbox Code Playgroud)

或者对于多重插入/更新:

$this->db->on_duplicate('table', array(
    array('column1' => 'value', 'column2' => 'value'),
    array('column1' => 'value', 'column2' => 'value')
));
Run Code Online (Sandbox Code Playgroud)


小智 6

以下过程在 Codeigniter 3.0.6 中对我有用

public function updateOnDuplicate($table, $data ) {
    if (empty($table) || empty($data)) return false;
    $duplicate_data = array();
    foreach($data AS $key => $value) {
        $duplicate_data[] = sprintf("%s='%s'", $key, $value);
    }

    $sql = sprintf("%s ON DUPLICATE KEY UPDATE %s", $this->db->insert_string($table, $data), implode(',', $duplicate_data));
    $this->db->query($sql);
    return $this->db->insert_id();
}
Run Code Online (Sandbox Code Playgroud)


Cal*_*lle 2

上面论坛主题的链接已损坏。我不知道比仅使用 db->query 进行调用更好的方法,如果有人有更好的解决方案,请发布。

$result = $this->CI->db->query(
    "INSERT INTO tablename (id, name, duplicate) VALUES (1, 'Joe', 1) ".
    "ON DUPLICATE KEY UPDATE duplicate=duplicate+1");
Run Code Online (Sandbox Code Playgroud)

我希望这可以帮助正在寻找解决方案的人。