Codigniter使用不同的ID更新表中的每一行

时间:2016-05-23 10:04:32

标签: php mysql codeigniter-3

我在数据库中有一个配置表,使用CI3。

每一行都有唯一的ID,以及type_name和type_desc。

因此,每行都有唯一的ID,如何使用一个update_batch查询更新整个表?

我显然不想在每一行上运行查询,所以我猜我需要用值构建一个数组,但是如何在数组中以某种方式使用where子句呢?!困惑。

我基本上需要这样做:

UPDATE check_types
SET type_name = POSTED_TYPE_NAME, type_desc = POSTED_TYPE_DESC
WHERE check_type_id = ???? POSTED_ID?????

1 个答案:

答案 0 :(得分:0)

我知道这样做的唯一方法是扩展db驱动程序。

在核心文件夹中创建名为MY_DB_mysqli_driver.php的文件。文件名假定config.php中定义的subclass_prefix是MY _

<?php

defined('BASEPATH') OR exit('No direct script access allowed');

class MY_DB_mysqli_driver extends CI_DB_mysqli_driver
{
    final public function __construct($params)
    {
        parent::__construct($params);
    }

    /**
     * Insert_On_Duplicate_Key_Update_Batch
     *
     * Compiles batch insert strings and runs the queries
     *
     * @param    string $table Table to insert into
     * @param    array $set An associative array of insert values
     * @param    bool $escape Whether to escape values and identifiers
     * @return    int    Number of rows inserted or FALSE on failure
     */
    public function insert_on_duplicate_update_batch($table = '', $set = NULL, $escape = NULL)
    {
        if ($set !== NULL)
        {
            $this->set_insert_batch($set, '', $escape);
        }

        if (count($this->qb_set) === 0)
        {
            // No valid data array. Folds in cases where keys and values did not match up
            return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE;
        }

        if ($table === '')
        {
            if (!isset($this->qb_from[0]))
            {
                return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
            }

            $table = $this->qb_from[0];
        }

        // Batch this baby
        $affected_rows = 0;
        for ($i = 0, $total = count($this->qb_set); $i < $total; $i += 100)
        {
            $this->query($this->_insert_on_duplicate_key_update_batch($this->protect_identifiers($table, TRUE, $escape, FALSE), $this->qb_keys, array_slice($this->qb_set, $i, 100)));
            $affected_rows += $this->affected_rows();
        }

        $this->_reset_write();
        return $affected_rows;
    }

    /**
     * Insert on duplicate key update batch statement
     *
     * Generates a platform-specific insert string from the supplied data
     *
     * @param    string $table Table name
     * @param    array $keys INSERT keys
     * @param    array $values INSERT values
     * @return    string
     */
    private function _insert_on_duplicate_key_update_batch($table, $keys, $values)
    {
        foreach ($keys as $num => $key)
        {
            $update_fields[] = $key . '= VALUES(' . $key . ')';
        }
        return "INSERT INTO " . $table . " (" . implode(', ', $keys) . ") VALUES " . implode(', ', $values) . " ON DUPLICATE KEY UPDATE " . implode(', ', $update_fields);
    }
}

您可以这样使用它:

$sql_array = array();
foreach ($data as $row)
{
    $arr = array(
            'check_type_id' => $row['check_type_id'], 
            'type_name' => $row['type_name'], 
            'type_desc' => $row['type_desc'] 
    );
    $sql_array[] = $arr;
}
$this->db->insert_on_duplicate_update_batch('check_types', $sql_array);