我正在尝试进入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);
我的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];
}
}
有人可以为此解释一下吗? PD。请不要建议使用自动数字ID,因为我从另一个系统移植。
答案 0 :(得分: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;
}
?>
答案 1 :(得分:16)
如果您没有执行返回数据的查询(即UPDATE,INSERT等),我认为PDOStatement :: closeCursor()不起作用。
更好的解决方案是在调用PDOStatement :: execute()之后简单地取消设置()PDOStatement对象:
$stmt = $pdo->prepare('UPDATE users SET active = 1');
$stmt->execute();
unset($stmt);
答案 2 :(得分:8)
问题似乎是---我对PDO不太熟悉---在你的getValue调用返回后,查询仍然绑定到连接(你只需要第一个值,但是连接返回几个,或者希望这样做。)
也许可以通过添加
来修复getValue$resul->closeCursor();
返回之前。
否则,如果对getValue的查询将始终返回单个(或足够少)值,则似乎首选使用fetchAll。
答案 3 :(得分:3)
我只花了15分钟谷歌在互联网上搜索,并查看至少5个不同的Stackoverflow问题,一些人声称我的错误显然来自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
无论如何,问题发生的原因是我的 original_bytes 和 new_bytes 都是unsigned bigints,这意味着如果我有一份工作,其中new_bytes实际上比original_bytes,然后我会有一个令人讨厌的MySQL“超出范围”错误。这只是在运行我的缩小服务一段时间后随机发生的。
为什么我得到这个奇怪的MySQL错误,而不是只是给我一个简单的错误,是超出我的!当我运行原始查询时,它实际上出现在SQLBuddy(轻量级PHPMyAdmin)中。 我有PDO异常,所以它应该给我MySQL错误。
没关系,底线是:
如果您收到此错误,请务必检查您的原始MySQL是否真的正确并且仍在工作!!!
答案 4 :(得分:0)
我的一个朋友在xampp 1.7.1版本中遇到了同样的问题。在通过5.2.9-2 php.net构建替换xampp / php / *并将所有必需的文件复制到xampp / apache / bin之后,它运行正常。
答案 5 :(得分:0)
如果您使用的是XAMPP 1.7.1,则只需升级到1.7.2。