У меня возникла странная проблема с 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, которая может повлиять на это поведение?
Спасибо.
Update: Пытался вызывать сообщения об ошибке:
$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)
);
Невероятно, не так ли? Мой подозреваемый теперь заключается в том, что существует некоторое специальное обновление beahaviour, специально сделанное для первого столбца каждой таблицы при обработке указателей PDO +.