How would I use ON DUPLICATE KEY UPDATE in my CodeIgniter model?

前端 未结 8 1532
暖寄归人
暖寄归人 2020-11-30 07:27

I have a CodeIgniter/PHP Model and I want to insert some data into the database.

However, I have this set in my \'raw\' SQL query:

ON DUPLICATE KEY U         


        
8条回答
  •  眼角桃花
    2020-11-30 08:19

    Following the snippet linked by Pickett, I made a few modifications to:

    1) Update it to use the new Query Builder (CI 3), formerly known as Active Record.

    2) You can now pass an associative array (key => value) or an array of associative arrays. In the second form, it performs a multi-update.

    I only tested it with mysqli, and it works well.

    This piece of code goes in 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;
    }
    

    And this goes into the /system/database/DB_query_builder.php file:

    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);
    }
    

    Then you can do this for a single row insert/update:

    $this->db->on_duplicate('table', array('column1' => 'value', 'column2' => 'value'));
    

    Or this for a multi insert/update:

    $this->db->on_duplicate('table', array(
        array('column1' => 'value', 'column2' => 'value'),
        array('column1' => 'value', 'column2' => 'value')
    ));
    

提交回复
热议问题