MySQLは1本のsqlを実現して大量のデータの更新を完成します


元の機能:
  • update categories SET display_order= 3,title = 'New Title 1' where id=1;
  • update categories SET display_order= 4,title = 'New Title 2' where id=2;
  • update categories SET display_order= 5,title = 'New Title 3' where id=3;

  • 機能の向上:
    UPDATE categories SET
        display_order = CASE id
            WHEN 1 THEN 3
            WHEN 2 THEN 4
            WHEN 3 THEN 5
        END,
        title = CASE id
            WHEN 1 THEN 'New Title 1'
            WHEN 2 THEN 'New Title 2'
            WHEN 3 THEN 'New Title 3'
        END
    WHERE id IN (1,2,3)

    PHP自動生成sql
    $data = [
        ['id' => 1, 'parent_id' => 100, 'title' => 'A', 'sort' => 1],
        ['id' => 2, 'parent_id' => 100, 'title' => 'A', 'sort' => 3],
        ['id' => 3, 'parent_id' => 100, 'title' => 'A', 'sort' => 5],
        ['id' => 4, 'parent_id' => 100, 'title' => 'B', 'sort' => 7],
        ['id' => 5, 'parent_id' => 101, 'title' => 'A', 'sort' => 9],
    ];
    
      ,    parent_id 100、title A       id    :
    
    /**
     *       
     * @param $tableName   
     * @param $data array       ,      
     * @param array $params array       ,         
     * @param string $field string       ,   id
     * @return bool|string
     */
    function batchUpdate($tableName,$data, $field, $params = [])
    {
       if (!is_array($data) || !$field || !is_array($params)) {
          return false;
       }
    
        $updates = parseUpdate($data, $field);
        $where = parseParams($params);
    
        //        $field   ,        ,   $fields   
        // array_column()    PHP5.5.0+,        ,      ,
        //     :http://php.net/manual/zh/function.array-column.php#118831
        $fields = array_column($data, $field);
        $fields = implode(',', array_map(function($value) {
            return "'".$value."'";
        }, $fields));
    
        $sql = sprintf("UPDATE `%s` SET %s WHERE `%s` IN (%s) %s", $tableName, $updates, $field, $fields, $where);
    
       return $sql;
    }
    
    /**
     *         CASE WHEN THEN       
     * @param $data array     
     * @param $field string   
     * @return string sql  
     */
    function parseUpdate($data, $field)
    {
        $sql = '';
        $keys = array_keys(current($data));
        foreach ($keys as $column) {
    
            $sql .= sprintf("`%s` = CASE `%s` 
    ", $column, $field); foreach ($data as $line) { $sql .= sprintf("WHEN '%s' THEN '%s'
    ", $line[$field], $line[$column]); } $sql .= "END,"; } return rtrim($sql, ','); } /** * where * @param $params * @return array|string */ function parseParams($params) { $where = []; foreach ($params as $key => $value) { $where[] = sprintf("`%s` = '%s'", $key, $value); } return $where ? ' AND ' . implode(' AND ', $where) : ''; }

    呼び出し:
    echo batchUpdate($data, 'id', ['parent_id' => 100, 'title' => 'A']);

    sqlの生成
    WHEN '1' THEN '1' 
    WHEN '2' THEN '2' 
    WHEN '3' THEN '3' 
    WHEN '4' THEN '4' 
    WHEN '5' THEN '5' 
    END,`parent_id` = CASE `id` 
    WHEN '1' THEN '100' 
    WHEN '2' THEN '100' 
    WHEN '3' THEN '100' 
    WHEN '4' THEN '100' 
    WHEN '5' THEN '101' 
    END,`title` = CASE `id` 
    WHEN '1' THEN 'A' 
    WHEN '2' THEN 'A' 
    WHEN '3' THEN 'A' 
    WHEN '4' THEN 'B' 
    WHEN '5' THEN 'A' 
    END,`sort` = CASE `id` 
    WHEN '1' THEN '1' 
    WHEN '2' THEN '3' 
    WHEN '3' THEN '5' 
    WHEN '4' THEN '7' 
    WHEN '5' THEN '9' 
    END WHERE `id` IN ('1','2','3','4','5')  AND `parent_id` = '100' AND `title` = 'A'
    

    参考記事:
    PHP一括更新