次のコードがあります。
$dbh = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $dbh->prepare("SELECT 1");
$stmt->execute();
$result = $stmt->fetch();
$stmt->execute();
$result = $stmt->fetch();
$stmt = $dbh->prepare("SELECT 1");
$stmt->execute();
$result = $stmt->fetch();
ただし、何らかの理由で、2 番目の準備済みステートメントを実行すると、次のエラーが発生します。
致命的なエラー: キャッチされない例外 'PDOException' とメッセージ 'SQLSTATE[HY000]: 一般エラー: 2014 他のバッファリングされていないクエリがアクティブな間はクエリを実行できません。PDOStatement::fetchAll() の使用を検討してください。または、コードが mysql に対してのみ実行される場合は、PDO::MYSQL_ATTR_USE_BUFFERED_QUERY 属性を設定して、クエリのバッファリングを有効にすることができます。
私はこのエラーが何を意味し、それをどのように修正するかを知っています (実行するか、unset($stmt);
または実行$stmt->closeCursor();
します)。私が理解していることから、それは通常、すべての結果を取得するfetch
代わりに行うことによって引き起こされます。fetchAll
ただし、この場合、結果は 1 つしかなく、フェッチされています。また、最初の準備済みステートメントを 1 回だけ実行すると、エラーは発生しません。最初のステートメントが2 回実行された場合にのみ発生します。また、 が の場合にのみ発生しPDO::ATTR_EMULATE_PREPARES
ますfalse
。
私の質問は、この場合に上記のエラーが発生する原因は何ですか? これまでに実行した他のクエリと何ら変わりはないようです。
Debian と CentOS の 2 つの Ubuntu 13.10 サーバーでこれをテストしましたが、デフォルトのパッケージを使用するとすべて同じエラーが発生します。
編集:
Ryan Vincent のコメントに答えるために、私は完全な mysqli 初心者ですが、以下にあるものは上記の例とほぼ同等であると信じています。私が間違っている場合は、私を修正してください。ただし、エラーは発生しないため、PDO のみのエラーのように見えます。
$mysqli = new mysqli($host, $user, $pass, $dbname);
if ($mysqli->connect_errno) {
die("Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error);
}
if (!($stmt = $mysqli->prepare("SELECT 1"))) {
die("Prepare 1 failed: (" . $mysqli->errno . ") " . $mysqli->error);
}
if (!$stmt->execute()) {
die("Execute 1 failed: (" . $stmt->errno . ") " . $stmt->error);
}
$stmt->store_result();
$stmt->bind_result($col1);
$stmt->fetch();
if (!$stmt->execute()) {
die("Execute 2 failed: (" . $stmt->errno . ") " . $stmt->error);
}
$stmt->store_result();
$stmt->bind_result($col1);
$stmt->fetch();
if (!($stmt = $mysqli->prepare("SELECT 1"))) {
// The following line is what fails in PDO
die("Prepare 2 failed: (" . $mysqli->errno . ") " . $mysqli->error);
}
if (!$stmt->execute()) {
die("Execute 3 failed: (" . $stmt->errno . ") " . $stmt->error);
}
$stmt->store_result();
$stmt->bind_result($col1);
$stmt->fetch();