最近有一个批量更新数据库表中某几个字段的需求,在做这个需求的时候,使用了PDO做参数绑定,其中遇到了一个坑。

方案选择

笔者已知的做批量更新有以下几种方案:

1、逐条更新

  这种是最简单的方案,但无疑也是效率最低的方案。

2、CASE WHEN

  类似如下的语句

    , );

PDO绑定参数

为了防止SQL注入,使用了PDO扩展绑定参数。上面的数字在一般情况下是变量,那么就需要做参数绑定。刚开始是想着在IN的时候将id组成的字符串作为变量绑定过去,第一次实现的代码如下:

 <?php
         $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函数的描述:

可以看到,说明里写的是会绑定一个PHP变量到占位符里,所以如果绑定了:ids为1, 2的字符串,那么MySQL解析语句的时候会将1,2解析为单个的变量,而不会当作一串。这也是PDO防SQL注入的原理,通过占位符的绑定,只将绑定的值当作一个值,而不是语句之类的其它东西,这样MySQL只会把传递过去的值当作一个变量的值。

修改后的写法:

 <?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?

原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

如果本文对你有帮助,请点下推荐,写文章不容易。

[PDO绑定参数]使用PHP的PDO扩展进行批量更新操作的更多相关文章

  1. Pdo 绑定参数方法 通用更新语句

    public  static  function upShelf($table,$arr,$where)    { //将传入的数组进行key vlaue 分离 并将key值以问号方式绑定参数     ...

  2. Yii 1.1 DAO绑定参数实例

    <?php $sql = "SELECT * FROM admin_user WHERE user_name=:uname AND password LIKE :c"; $c ...

  3. [猜你喜欢]冠军“yes,boy!”分享,含竞赛源代

    [猜你喜欢]冠军“yes,boy!”分享,含竞赛源代码  DataCastle运营 发表于 2016-7-20 17:31:52      844  3  5 我是Yes,boy! ,来自东北大学计算 ...

  4. 图像显示 imshow()[OpenCV 笔记5]

    void imshow(const string& winname InputArray mat); winname 窗口表识名称 mat 需要显示的图像.InputArray类型,声明如下 ...

  5. Hibernate绑定参数

    使用绑定参数的优势: 我们为什么要使用绑定命名参数?任何一个事物的存在都是有其价值的,具体到绑定参数对于HQL查询来说,主要有以下两个主要优势:①. 可以利用数据库实施性能优化 因为对Hibernat ...

  6. thinkphp5.0学习笔记(三)获取信息,变量,绑定参数

    1.构造函数: 控制器类必须继承了\think\Controller类,才能使用: 方法_initialize 代码: <?php namespace app\lian\controller; ...

  7. [转载]mysql绑定参数bind_param原理以及防SQL注入

    假设我们的用户表中存在一行.用户名字段为username.值为aaa.密码字段为pwd.值为pwd.. 下面我们来模拟一个用户登录的过程.. <?php $username = "aa ...

  8. mysql绑定参数bind_param原理以及防SQL注入

    假设我们的用户表中存在一行.用户名字段为username.值为aaa.密码字段为pwd.值为pwd.. 下面我们来模拟一个用户登录的过程.. <?php $username = "aa ...

  9. SpringMVC中,前台jsp封装参数,绑定参数,传递参数到后台controller的过程详解

    前台到后台的流程:前台jsp->后台:controller控制器层->service业务层->DAO数据访问层->数据库model模型层. 从上面流程可知,前台jsp的数据,想 ...

随机推荐

  1. 【Java远程debug】

    转自 http://blog.csdn.net/hongchangfirst/article/details/44191925 一.远程debug原理 Java远程调试的原理是两个JVM之间通过deb ...

  2. [Idea] 在idea中使用jetty debug

    1.添加jetty的maven插件 <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId> ...

  3. Mesos高可用解决方案剖析

    本文作者王勇桥,80后的IT攻城狮,供职于IBM多年,Mesos和Swarm社区的贡献者.本文是他根据自己对Mesos的高可用(High-Availability)设计方案的了解以及在Mesos社区贡 ...

  4. WEB开发入门

    对服务器的概念需要更新一下: 从物理上来说,服务器就是一台PC机,至少8核,以T计算,带宽100M以上 一般有的服务器 1. web服务器 -- PC机上安装一个具有web服务的软件 2. 数据库服务 ...

  5. Vue - 事件绑定

    1.内联方式: A:将事件处理器绑定到一个方法中,以下所有事件都以click事件作为案例 注意:内联方式下事件处理器只能绑定一个方法,要是想要绑定多个方法,依旧还是使用js中的addEventList ...

  6. iOS 真机测试时报错:Provisioning profile "iOS Team Provisioning Profile: XXX” doesn't include the currently selected device “XXX”.

    这几天因工作需要,去给客户演示iOS项目打包的过程.之前演示都是顺利的,但后来客户自己操作时打电话说遇到了问题,出现报错. 就过去看了一下,发现一个很陌生的错误提示: The operation co ...

  7. java微信公众号开发----搭建ngrok环境

    下载ngrok,一个能够在公网安全访问内网Web主机的工具 下载地址:http://download.csdn.net/download/u014252425/9389847,亲测可用 下载完成后,进 ...

  8. Ice-E(Embedded Internet Communications Engine)移植到s3c2440A(arm9)linux(2.6.12)上的

    2009-03-26 18:31:31 原文链接 1.前言 ICE-E是ICE在嵌入式上运行的一个版本,与ICE比较如下: Category Ice 3.3.0 Ice-E 1.3.0 Thread ...

  9. JS+CSS 钟表

    .<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title& ...

  10. [DataMining]WEEK1 - text-retrieval and search engine

    What does a computer have to do in order to understand a natural language sentence? What is ambiguit ...