【发布时间】:2012-03-01 20:29:21
【问题描述】:
我在使用 php PDO 和 mysql 时遇到了一个奇怪的问题。
我有下表:
create table test_table ( id integer, value text );
单行:
insert into test_table values (1, "asdf");
当我尝试使用准备好的语句更新这一行时,根据我使用的语法,我得到了不同的行为:
// connection to db (common code)
$dbh = new PDO("mysql:host=localhost;dbname=test", "myuser", "mypass");
================================================ ==========
// WORKING
$q = 'update test_table set id=1, value='.rand(0,99999).' where id=1';
$dbh->exec($q);
================================================ ==========
// WORKING
$q = 'update test_table set value=:value where id=:id';
$par = array(
"id" => 1,
"value" => rand(0,99999)
);
$sth = $dbh->prepare($q, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$sth->execute($par);
================================================ ==========
// NOT WORKING
$q = 'update test_table set id=:id, value=:value where id=:id';
$par = array(
"id" => 1,
"value" => rand(0,99999)
);
$sth = $dbh->prepare($q, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$sth->execute($par);
在第三种情况下,在我的服务器上,没有对行执行更新,没有任何原因,也没有异常/错误。在另一台服务器上它可以工作。我不是在寻找类似的答案:“所以?使用第一个或第二个实现”:)
我在问为什么第三个实现不起作用,因为我正在将大量代码从服务器迁移到另一台(这不是我的代码),它包含很多查询像这个,我没有时间一一修复。在当前服务器上可以正常工作,而在新服务器上则不行。
为什么第三个实现不起作用? php/pdo/mysql 是否有任何可能影响此行为的配置?
谢谢。
更新: 试图挤出错误信息:
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
try {
// NOT WORKING
$q = 'update test_table set id=:id, value=:value where id=:id';
$par = array(
"id" => 1,
"value" => rand(0,99999)
);
$sth = $dbh->prepare($q, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
print_r($sth);
print_r($dbh->errorInfo());
} catch(PDOException $e) {
echo $e->getMessage();
}
$sth->execute($par);
在两台服务器上执行此代码(工作和不工作):
PDOStatement Object
(
[queryString] => update test_table set id=:id, value=:value where id=:id
)
Array
(
[0] => 00000
[1] =>
[2] =>
)
更新 2
看看这个进一步的测试:
create table test_table ( value0 text, value text );
insert into test_table values ("1", "pippo");
// NOT WORKING
$q = 'update test_table set value0=:value0, value=:value where value0=:value0';
$par = array(
"value0" => "1",
"value" => rand(0, 839273)
);
create table test_table ( value0 text, value text );
insert into test_table values ("pippo", "1");
// WORKING
$q = 'update test_table set value=:value, value0=:value0 where value=:value';
$par = array(
"value" => "1",
"value0" => rand(0, 839273)
);
难以置信,不是吗?我现在怀疑存在一些专门针对 PDO+占位符处理的每个表的 第一列 的特殊更新行为。
【问题讨论】:
-
您正在使用 :id 来更改 'id' 的值以及识别行。你确定这是你想做的吗?
-
@middus:正如他所说:“我正在将大量代码从服务器迁移到另一台(不是我的代码),它包含很多像这样的查询,我没有时间一个一个地修复它们”
-
我知道,这不是我的代码。我永远不会那样做。不过,我想知道为什么它不能在服务器上运行而在另一个服务器上运行。
-
服务器之间还有什么其他的不同点吗?也许一个数据库有一个关于 id 的索引而一个没有,或者你能想到的任何其他东西?正如你所说,给定这些版本,mysql 版本似乎不可行。