我正在使用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。
答案 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();