PDO准备状态与手动查询没有给出相同的结果

时间:2014-12-27 16:27:53

标签: php mysql pdo prepared-statement

我正在使用PHP和PDO预处理语句来访问数据库。我有这个准备好的查询,我想执行(通过foreach循环多次,但我没有看到影响这个真的):

insert into forum_access (forum_id, user_id) select * from (select ?, ?)
 as tmp where not exists (select * from forum_access 
 where forum_id = ? and user_id = ?) limit 1

然后我使用PDO执行数组中的变量来执行此语句,如下所示:

$values = Array(2, 1, 2, 1); // Normally it's variables here
$stmt->execute($values);

这会执行,但奇怪的是它会将一个带有值(2,2)的行插入到forum_access中。真正奇怪的是,当我使用手动插入的变量运行SQL查询时,如下所示:

insert into forum_access (forum_id, user_id) select * from (select 2, 1)
 as tmp where not exists (select * from forum_access 
 where forum_id = 2 and user_id = 1) limit 1

它正确插入一个值为(2,1)的行。

我希望这与PDO / MySQL处理预准备语句的方式有关。我或多或少是准备好的陈述的新手,不知道这里出了什么问题。希望其他人可以对此有所了解。

注意: 我有理由使用相当复杂的插入...选择查询而不是重复键上的插入....也许不是完美的理由,但足够好,不会对从根本上改变查询的建议感兴趣。

在WAMP服务器上使用PHP 5.3和MySQL 5.0。

3 个答案:

答案 0 :(得分:2)

$SQL = 'insert into forum_access (forum_id, user_id) 
        select * 
        from (select :forum_id1, :user_id1) as tmp 
        where not exists (
             select * 
             from forum_access 
             where forum_id = :forum_id2 and user_id = :user_id2) 
        limit 1';

$forum_id1 = 2;
$user_id1  = 1;
$forum_id2 = 2;
$user_id2  = 1;

$stmt = $dbh->prepare($SQL);

$stmt->bindParam(':forum_id1', $forum_id1, PDO::PARAM_INT);
$stmt->bindParam(':user_id1',  $user_id1,  PDO::PARAM_INT);
$stmt->bindParam(':forum_id2', $forum_id2, PDO::PARAM_INT);
$stmt->bindParam(':user_id2',  $user_id2,  PDO::PARAM_INT);

$stmt->execute();

答案 1 :(得分:2)

我自己解决了这个问题。似乎MySQL对select语句中的插入值感到困惑,并将它们混合起来。我试着命名这些值,如下所示:

insert into forum_access (forum_id, user_id) select * from 
 (select ? as forum_id, ? as user_id) as tmp 
 where not exists (select * from forum_access 
 where forum_id = ? and user_id = ?) limit 1

并且看哪,这确实有效。

我仍然不确定它为什么会起作用。但我最关心的是获得一个有效的应用程序,所以目前我很满意。

感谢您的所有帮助,抱歉打扰我能做到并且自己解决的问题。

答案 2 :(得分:1)

更改此

$values = Array(2, 1, 2, 1); // Normally it's variables here
$stmt->execute($values);

用这个

$values = Array(2, 1, 2, 1);
for($i=0;$i<count($values);$i++) {
$stmt->bindParam(($i+1),$values[$i]); 
}
$stmt->execute();