我遇到了这个让我完全难过的问题.这是我的执行模式. PDO调用嵌套在foreach循环中.
foreach(){
foreach(){
}
}
我正在使用PDO和MySQL,当我背靠背执行UPDATE查询时,它们会在循环中相互干扰.我知道他们可以单独评论一组,然后执行另一组.这是我正在处理的代码模板:
$set_data1 = "UPDATE data_table
SET data_status = 'PROCESSED'
WHERE data_id = :data_id1";
$stmt = $db->prepare($set_data1);
$stmt->bindParam(':data_id1', $data_array1['data_id'], PDO::PARAM_INT);
$stmt->execute();
$set_data2 = "UPDATE data_table
SET data_status = 'PENDING'
WHERE data_id = :data_id2";
$stmt = $db->prepare($set_data2);
$stmt->bindParam(':data_id2', $data_array2['data_id'], PDO::PARAM_INT);
$stmt->execute();
出于某种原因,当在嵌套的foreach循环中执行两个查询时,来自$set_data1的数据将被$set_data2取消.我试过用$stmt-> closeCursor()关闭光标;我尝试使用单个语句进行准备,并将新参数绑定到语句中.我已经尝试将$stmt和$db实例设置为null,然后重新实例化它们无济于事.我已经尝试在查询中使用CASE THEN和IF条件…没有.关于问题的任何信息都会很精彩.我不知道PDO是否在循环内的同一个表上调用UPDATES时出错,因为我在其他地方从未遇到过这个问题.提前致谢!
解决方法:
对于初学者,你使用bindParam()就像它的bindValue()一样,它们是quite different.
如果没有看到你从哪里得到你的数组值,那就更难以确定是什么了.看起来您提供的信息实际上可能不是您正在使用的代码并且已被修改,特别是关于foreach循环和data_array变量,因为您所描述的是BindParam常见的问题所以这是我的假设我会继续努力.如果是这种情况,通常最好提供实际的代码片段,包括使用的变量的初始化和发现问题的块,而不仅仅是这些块中的代码.
这是另一个答案with why,基本上确保你通过引用foreach循环的值部分或者将bindParams更改为bindValues.如果您计划继续使用此结构,那么您还需要确保在此处使用两个单独的对象而不是一个,因为每次调用execute()时都运行bindParam()方法.
所以,比方说,代码结构没有改变(它可能应该是因为它全部在循环中,只有Execute应该在循环中):
$set_data1 = "UPDATE data_table
SET data_status = 'PROCESSED'
WHERE data_id = :data_id1";
$stmt = $db->prepare($set_data1);
$stmt->bindValue(':data_id1', $data_array1['data_id'], PDO::PARAM_INT);
$stmt->execute();
$set_data2 = "UPDATE data_table
SET data_status = 'PENDING'
WHERE data_id = :data_id2";
$stmt2 = $db->prepare($set_data2);
$stmt2->bindValue(':data_id2', $data_array2['data_id'], PDO::PARAM_INT);
$stmt2->execute();
更好的方法是这样做(请记住这只是一个普遍的例子):
$set_data = "UPDATE data_table
SET data_status = :data_status
WHERE data_id = :data_id";
$data_array = array( array('data_status' => $dataStatus1, 'data_id' => $dataId), array('data_status' => $dataStatus2, 'data_id' => $dataId2) );
/* this is just to represent a multidimensional array (or a multidimensional object) containing the data status and the data id which should be handled and decided before you pass them into a loop. */
$stmt = $db->prepare($set_data);
$data_status = null;
$data_id = null;
$stmt->bindParam(':data_status', $data_status);
$stmt->bindParam(':data_id', $data_id);
foreach( $data_array as $name => $val ) {
$data_status = $val['data_status'];
$data_id = $val['data_id'];
$stmt->execute()';
}