我正在尝试进入PDO细节.所以我编码了这个:
$cn = getConnection();
// get table sequence
$comando = "call p_generate_seq('bitacora')";
$id = getValue($cn, $comando);
//$comando = 'INSERT INTO dsa_bitacora (id, estado, fch_creacion) VALUES (?, ?, ?)';
$comando = 'INSERT INTO dsa_bitacora (id, estado, fch_creacion) VALUES (:id, :estado, :fch_creacion)';
$parametros = array (
':id'=> (int)$id,
':estado'=>1,
':fch_creacion'=>date('Y-m-d H:i:s')
);
execWithParameters($cn, $comando, $parametros);
Run Code Online (Sandbox Code Playgroud)
我的getValue函数工作正常,我得到了表的下一个序列.但是当我进入execWithParameters时,我得到了这个异常:
PDOException:SQLSTATE [HY000]:常规错误:2014在其他未缓冲的查询处于活动状态时无法执行查询.考虑使用PDOStatement :: fetchAll().或者,如果您的代码只是针对mysql运行,则可以通过设置PDO :: MYSQL_ATTR_USE_BUFFERED_QUERY属性来启用查询缓冲.在第77行的D:\ Servidor\xampp_1_7_1\htdocs\bitacora\func_db.php中
我试图修改连接属性,但它不起作用.
这些是我的核心数据库功能:
function getConnection() {
try {
$cn = new PDO("mysql:host=$host;dbname=$bd", $usuario, $clave, array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
));
$cn->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
return $cn;
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
}
function getValue($cn, $comando) {
$resul = $cn->query($comando);
if (!$resul) return null;
while($res = $resul->fetch()) {
$retorno = $res[0][0];
break;
}
return $retorno;
}
function execWithParameters($cn, $comando, $parametros) {
$q = $cn->prepare($comando);
$q->execute($parametros);
if ($q->errorInfo() != null) {
$e = $q->errorInfo();
echo $e[0].':'.$e[1].':'.$e[2];
}
}
Run Code Online (Sandbox Code Playgroud)
有人可以为此做点什么?PD.请不要建议做自动数字ID,因为我从另一个系统移植.
Wez*_*ong 22
问题是mysql只允许在给定时间有一个未完成的游标.通过使用fetch()方法而不消耗所有挂起的数据,您将打开游标.
建议的方法是使用fetchAll()方法使用所有数据.另一种方法是使用closeCursor()方法.
如果你改变这个功能,我想你会更快乐:
<?php
function getValue($cn, $comando) {
$resul = $cn->query($comando);
if (!$resul) return null;
foreach ($resul->fetchAll() as $res) {
$retorno = $res[0];
break;
}
return $retorno;
}
?>
Run Code Online (Sandbox Code Playgroud)
Jon*_*ill 16
如果你没有做一个返回数据的查询(即UPDATE,INSERT等),我认为PDOStatement :: closeCursor()不会起作用.
更好的解决方案是在调用PDOStatement :: execute()之后简单地取消设置()PDOStatement对象:
$stmt = $pdo->prepare('UPDATE users SET active = 1');
$stmt->execute();
unset($stmt);
Run Code Online (Sandbox Code Playgroud)
问题似乎是---我对PDO不太熟悉---在你的getValue调用返回后,查询仍然绑定到连接(你只需要第一个值,但连接返回几个,或者希望这样做).
也许getValue可以通过添加来修复
$resul->closeCursor();
Run Code Online (Sandbox Code Playgroud)
在返回之前.
否则,如果对getValue的查询将始终返回单个(或足够少)值,则似乎首选使用fetchAll.
我只花了 15 分钟在互联网上谷歌搜索,并查看了至少 5 个不同的 Stackoverflow 问题,其中一些人声称我的 bug 显然是由错误版本的 PHP、错误版本的 MySQL 库或任何其他神奇的黑盒东西引起的......
我将所有代码更改为使用“fetchAll”,甚至在每次查询后对查询对象调用 closeCursor() 和 unset() 。老实说我已经绝望了!我还尝试了 MYSQL_ATTR_USE_BUFFERED_QUERY 标志,但它不起作用。
最后,我把所有的事情都扔到了窗外,查看了 PHP 错误,并跟踪了发生错误的代码行。
SELECT AVG((original_bytes-new_bytes)/original_bytes) as saving
FROM (SELECT original_bytes, new_bytes FROM jobs ORDER BY id DESC LIMIT 100) AS t1
Run Code Online (Sandbox Code Playgroud)
不管怎样,问题发生是因为我的original_bytes和new_bytes都是无符号的bigints,这意味着如果我曾经有过一份工作,其中new_bytes实际上比original_bytes大,那么我就会遇到令人讨厌的MySQL“超出范围”错误。这只是在运行我的缩小服务一段时间后随机发生的。
为什么我会得到这个奇怪的 MySQL 错误而不是仅仅给我简单的错误,这超出了我的范围!当我运行原始查询时,它实际上出现在 SQLBuddy(轻量级 PHPMyAdmin)中。我打开了 PDO 异常,所以它应该给我 MySQL 错误。
没关系,底线是:
如果您遇到此错误,请务必检查您的原始 MySQL 是否确实正确并且仍在工作!
| 归档时间: |
|
| 查看次数: |
34724 次 |
| 最近记录: |