Я так озадачен этим.
У меня есть некоторый код, который генерирует запросы на обновление, готовит, связывает их, а затем выполняет. Первый запрос выполняется успешно, но затем подготовка завершается неудачно для второго. Запрос очень прост. Я очень запутался, потому что журналы mysql показывают подготовленный запрос, и я могу вручную выполнить его в mysql. Рассмотрим следующий код:
$set = null;
foreach($editable as $field => $value) {
if(!empty($value))
$set .= $field."=?,";
}
$set = substr($set, 0, -1);
// generate the update query based on object data, and execute it
$stmt = $this->dbh->stmt_init() or die("stmt_init: ".$this->dbh->error);
$stmt->prepare("UPDATE ".$this->table_name."SET ".$set."WHERE ".$whereclause) or die("prepare failed: ".$this->dbh->error." (".$stmt->sqlstate.")");
if($stmt->error) die($stmt->error);
$this->bindParameters($stmt, $editable);
$stmt->execute();
$stmt->close();function bindParameters(&$statement, &$params) {
echo "<pre>";
var_dump($statement);
echo "</pre>";
$args = array();
// just assume every value is string type
$args[] = implode('', array_map(function($v) {
return "d";
},
array_values($params)));
foreach ($params as $paramName => $value) {
$args[] = &$params[$paramName];
//$params[$paramName] = null;
}
var_dump($args);
//die();
call_user_func_array(array(&$statement, 'bind_param'), $args);
}
Первая часть выполняется в цикле, где $ editable представляет собой массив имен и значений полей. $ whereClause всегда равно «client_id = 83». $ this-> dbh содержит объект соединения. Этот код отлично работает для первого обновления, но не для второго. он генерирует такие запросы:
UPDATE client_rate SET rate=? WHERE client_id=83
И это создает следующее:
UPDATE client_rate SET rate=99 WHERE client_id=83
UPDATE client_rate SET rate=165 WHERE client_id=83
Второй — тот, который терпит неудачу с синтаксической ошибкой. Журналы mysql показывают эти запросы, и я могу запустить их вручную без ошибок.
Ошибка отображается точно так:
prepare failed: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE client_id=83' at line 3 (42000)
Это то, что я вижу в журналах запросов mysql, связанных с этим:
19954 Query SELECT * FROM client_rate LIMIT 0
19954 Query SELECT * FROM client_rate WHERE client_id=83
19954 Prepare UPDATE client_rate
SET rate=?
WHERE client_id=83
19954 Execute UPDATE client_rate
SET rate=99
WHERE client_id=83
19954 Close stmt
19954 Query SELECT * FROM client_rate WHERE client_id=83
19954 Prepare UPDATE client_rate
SET rate=?
WHERE client_id=83
19954 Execute UPDATE client_rate
SET rate=165
WHERE client_id=83
19954 Close stmt
Что, черт возьми, я могу делать неправильно, что заставит подготовиться к обнаружению ошибки?
ОБНОВИТЬ:
Когда я удаляю все проверки ошибок, я вижу, что БД действительно выполняет запросы нормально. Я просто получаю следующее несколько раз на своей странице:
Warning: mysqli_stmt::bind_param(): invalid object or resource mysqli_stmt
Что-нибудь очевидное, может быть, я скучаю?
Ну, в конце концов, я, честно говоря, не знаю, что вызвало это. Я заметил, что мой код отладки действительно накапливался, пытаясь решить эту проблему, поэтому я вернул свою рабочую копию. Затем он загадочным образом начал работать.
Я не уверен, что я сделал, чтобы сломать это в первую очередь, но теперь это работает …
Других решений пока нет …