[PDO绑定参数]使用PHP的PDO扩展进行批量更新操作
最近有一个批量更新数据库表中某几个字段的需求,在做这个需求的时候,使用了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语句里面做参数绑定时应该一个一个的绑定。
参考链接:
Can I bind an array to an IN() condition?
原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。
如果本文对你有帮助,请点下推荐,写文章不容易。
[PDO绑定参数]使用PHP的PDO扩展进行批量更新操作的更多相关文章
- Pdo 绑定参数方法 通用更新语句
public static function upShelf($table,$arr,$where) { //将传入的数组进行key vlaue 分离 并将key值以问号方式绑定参数 ...
- Yii 1.1 DAO绑定参数实例
<?php $sql = "SELECT * FROM admin_user WHERE user_name=:uname AND password LIKE :c"; $c ...
- [猜你喜欢]冠军“yes,boy!”分享,含竞赛源代
[猜你喜欢]冠军“yes,boy!”分享,含竞赛源代码 DataCastle运营 发表于 2016-7-20 17:31:52 844 3 5 我是Yes,boy! ,来自东北大学计算 ...
- 图像显示 imshow()[OpenCV 笔记5]
void imshow(const string& winname InputArray mat); winname 窗口表识名称 mat 需要显示的图像.InputArray类型,声明如下 ...
- Hibernate绑定参数
使用绑定参数的优势: 我们为什么要使用绑定命名参数?任何一个事物的存在都是有其价值的,具体到绑定参数对于HQL查询来说,主要有以下两个主要优势:①. 可以利用数据库实施性能优化 因为对Hibernat ...
- thinkphp5.0学习笔记(三)获取信息,变量,绑定参数
1.构造函数: 控制器类必须继承了\think\Controller类,才能使用: 方法_initialize 代码: <?php namespace app\lian\controller; ...
- [转载]mysql绑定参数bind_param原理以及防SQL注入
假设我们的用户表中存在一行.用户名字段为username.值为aaa.密码字段为pwd.值为pwd.. 下面我们来模拟一个用户登录的过程.. <?php $username = "aa ...
- mysql绑定参数bind_param原理以及防SQL注入
假设我们的用户表中存在一行.用户名字段为username.值为aaa.密码字段为pwd.值为pwd.. 下面我们来模拟一个用户登录的过程.. <?php $username = "aa ...
- SpringMVC中,前台jsp封装参数,绑定参数,传递参数到后台controller的过程详解
前台到后台的流程:前台jsp->后台:controller控制器层->service业务层->DAO数据访问层->数据库model模型层. 从上面流程可知,前台jsp的数据,想 ...
随机推荐
- DTMF三种模式(SIPINFO,RFC2833,INBAND)
转自:http://www.tuicool.com/articles/n6Vb2iJ 1.DTMF(双音多频)定义:由高频音和低频音的两个正弦波合成表示数字按键(0~9 * # A B C D). 2 ...
- 虚拟机下CentOS 配置IP地址的三种方法
1.自动获取IP地址(我不是用的这种方法,不做过多介绍) 虚拟机使用桥接模式,相当于连接到物理机的网络里,物理机网络有DHCP服务器自动分配IP地址. #dhclient 自动获取ip地址命令 #if ...
- mysql乐观锁总结和实践
乐观锁介绍: 乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突 ...
- CC2530使用串口下载(SBL)
工作环境: WIN7 64位 IAR 版本: 8.10.3 (8.10.3.10338) ZStack-CC2530-2.3.1-1.4.0协议栈,下载地址:http://download.csdn. ...
- FZU 1914 单调队列
题目链接:http://acm.fzu.edu.cn/problem.php?pid=1914 题意: 给出一个数列,如果它的前i(1<=i<=n)项和都是正的,那么这个数列是正的,问这个 ...
- Format
strTimeZone := Format('%s ~ %s',[formatdatetime('yyyy-mm-dd',dtpStartTime.DateTime), formatdatetime( ...
- Maven打包生成可运行bat/sh脚本文件
利用Maven的appassembler-maven-plugin插件,就可以实现自动打包可运行的脚本,还可以跨平台. <plugin> <groupId>org ...
- 封装jdbc 单例模式的应用
实现增删该查的jdbc封装 import java.io.IOException; import java.io.InputStream; import java.sql.Connection; im ...
- 一些关于HTML与CSS的总结与实际应用
//学习前端也快一年了,觉得有必要好好总结一下这一年来学过的知识.一些是前辈们的精华,文章最后会讲地址一一放出,若原作者有任何介意,请及时联系我删除. 关于DOCTYPE 1.DOCTYPE的作用是什 ...
- BZOJ 2342 & manachar+最优性剪枝
题意: 求最长回文串,串的两边都是回文串. Solution: manachar预处理然后暴力找... Code: #include <iostream> #include <cst ...