[pdo绑定参数]使用php的pdo扩展进行批量更新操作,pdo绑定最近有一个批量更新数据库表中某几个字段的需求,在做这个需求的时候,使用了pdo做参数绑定,其中遇到了一个坑。
方案选择笔者已知的做批量更新有以下几种方案:
1、逐条更新
这种是最简单的方案,但无疑也是效率最低的方案。
2、case when
类似如下的语句
update tbl_test set val = case id when 1 then 2 when 2 then 3 end where id in(1, 2);
pdo绑定参数为了防止sql注入,使用了pdo扩展绑定参数。上面的数字在一般情况下是变量,那么就需要做参数绑定。刚开始是想着在in的时候将id组成的字符串作为变量绑定过去,第一次实现的代码如下:
1 1, 'val' => 2), array('id' => 2, 'val' => 3)); 3 $ids = implode(',', array_map(function($v) {return $v['id'];}, $data)); //获取id数组 4 $update_sql = 'update tbl_test set val = case id'; 5 $params = array(); 6 $params[:ids] = $ids; 7 foreach($data as $key => $item) { 8 $update_sql .= when :id_ . $key . then :val_ . $key . ; 9 $params[:id_ . $key] = $item['id'];10 $params[:val_ . $key] = $item['val'];11 }12 $update_sql .= end where id in (:_ids);13 test::execute($update_sql, $params);//此处会调用bindparam绑定参数
后来发现这样是行不通的,而且比较诡异的是这样只能更新第一条记录。查阅资料后,发现这样的绑定方式是不行的,in语句的参数应该一个一个地绑定。看看文档中对bindparam函数的描述:
可以看到,说明里写的是会绑定一个php变量到占位符里,所以如果绑定了:ids为1, 2的字符串,那么mysql解析语句的时候会将1,2解析为单个的变量,而不会当作一串。这也是pdo防sql注入的原理,通过占位符的绑定,只将绑定的值当作一个值,而不是语句之类的其它东西,这样mysql只会把传递过去的值当作一个变量的值。
修改后的写法:
1 1, 'val' => 2), array('id' => 2, 'val' => 3)); 3 $update_sql = 'update tbl_test set val = case id'; 4 $params = array(); 5 $params[:ids] = $ids; 6 $in_arr = array(); 7 8 foreach($data as $key => $item) { 9 $update_sql .= when :id_ . $key . then :val_ . $key . ;10 $params[:id_ . $key] = $item['id'];11 $params[:val_ . $key] = $item['val'];12 $params[:ids_ . $key] = $item['id'];13 array_push($in_arr, :id_ . $key);14 }15 $update_sql .= end where id in ( . implode(',' $in_arr) . );16 test::execute($update_sql, $params);//此处会调用bindparam绑定参数
总结这是最近遇到的一个小问题,其实更多的是说明在mysql的in语句里面做参数绑定时应该一个一个的绑定。
参考链接:
mysql语句:批量更新多条记录的不同值
can i bind an array to an in() condition?
原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。
如果本文对你有帮助,请点下推荐,写文章不容易。
http://www.bkjia.com/phpjc/1122769.htmlwww.bkjia.comtruehttp://www.bkjia.com/phpjc/1122769.htmltecharticle[pdo绑定参数]使用php的pdo扩展进行批量更新操作,pdo绑定 最近有一个批量更新数据库表中某几个字段的需求,在做这个需求的时候,使用...