[PDO綁定參數]使用PHP的PDO擴展進行批量更新操做

最近有一個批量更新數據庫表中某幾個字段的需求,在作這個需求的時候,使用了PDO作參數綁定,其中遇到了一個坑。php

方案選擇

筆者已知的作批量更新有如下幾種方案:mysql

一、逐條更新sql

這種是最簡單的方案,但無疑也是效率最低的方案。數據庫

二、CASE WHEN數組

相似以下的語句函數

UPDATE tbl_test SET val = CASE id WHEN 1 THEN 2 WHEN 2 THEN 3 END WHERE id IN(1, 2);

PDO綁定參數spa

爲了防止SQL注入,使用了PDO擴展綁定參數。上面的數字在通常狀況下是變量,那麼就須要作參數綁定。剛開始是想着在IN的時候將id組成的字符串做爲變量綁定過去,第一次實現的代碼以下:code

<?phpip

$data = array(array('id' => 1, 'val' => 2), array('id' => 2, 'val' => 3));
    $ids = implode(',', array_map(function($v) {return $v['id'];}, $data)); //獲取ID數組
    $update_sql = 'UPDATE tbl_test SET val = CASE id';
    $params = array();
    $params[":ids"] = $ids;
    foreach($data as $key => $item) {
            $update_sql .= "WHEN :id_" . $key . "THEN :val_" . $key . " ";
            $params[":id_" . $key] = $item['id'];
            $params[":val_" . $key] = $item['val'];
    }
    $update_sql .= "END WHERE id IN (:_ids)";
    TEST::execute($update_sql, $params);//此處會調用bindParam綁定參數

後來發現這樣是行不通的,並且比較詭異的是這樣只能更新第一條記錄。查閱資料後,發現這樣的綁定方式是不行的,IN語句的參數應該一個一個地綁定。看看文檔中對bindParam函數的描述:文檔

PDO描述

修改後的寫法:

<?php
     $data = array(array('id' => 1, 'val' => 2), array('id' => 2, 'val' => 3));
     $update_sql = 'UPDATE tbl_test SET val = CASE id';
     $params = array();
     $params[":ids"] = $ids;
     $in_arr = array();

     foreach($data as $key => $item) {
             $update_sql .= "WHEN :id_" . $key . "THEN :val_" . $key . " ";
             $params[":id_" . $key] = $item['id'];
             $params[":val_" . $key] = $item['val'];
             $params[":ids_" . $key] = $item['id'];
             array_push($in_arr, ":id_" . $key);
     }
     $update_sql .= "END WHERE id IN (" . implode(',' $in_arr) . ")";
     TEST::execute($update_sql, $params);//此處會調用bindParam綁定參數

總結

這是最近遇到的一個小問題,其實更多的是說明在MySQL的IN語句裏面作參數綁定時應該一個一個的綁定。

參考連接:
mysql語句:批量更新多條記錄的不一樣值
Can I bind an array to an IN() condition?

原創文章,文筆有限,才疏學淺,文中如有不正之處,萬望告知。

若是本文對你有幫助,請點下推薦,寫文章不容易。

相關文章
相關標籤/搜索