Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

PDO “Pengecualian tidak tertangkap 'PDOException' .. Tidak dapat mengeksekusi kueri saat kueri tanpa buffer lainnya aktif. Pertimbangkan untuk menggunakan PDOStatement::fetchAll().”

Anda perlu mengambil hingga upaya pengambilan baris gagal. Saya tahu Anda mungkin hanya memiliki satu baris di kumpulan hasil dan berpikir satu pengambilan sudah cukup, tetapi tidak (ketika Anda menggunakan kueri tanpa buffer). PDO tidak mengetahui berapa banyak baris yang ada hingga mencapai akhir, di mana ia mencoba mengambil baris berikutnya, tetapi gagal.

Anda mungkin memiliki pernyataan lain di mana Anda tidak sepenuhnya "mengambil sampai pengambilan gagal". Ya, saya melihat Anda mengambil sampai pengambilan gagal untuk satu pernyataan, tetapi itu tidak berarti Anda melakukannya untuk semuanya.

Untuk memperjelas -Saat Anda menjalankan kueri melalui execute(), Anda membuat kumpulan hasil yang harus diambil dari db ke php. PDO hanya dapat menangani 1 dari "hasil yang sedang dalam proses diambil" ini pada satu waktu (per koneksi). Anda harus benar-benar mengambil kumpulan hasil, sampai akhir, sebelum Anda dapat mulai mengambil kumpulan hasil yang berbeda dari panggilan yang berbeda ke execute().

Saat Anda "memanggil fetch() hingga fetch() gagal", fakta bahwa Anda mencapai akhir hasil dicatat secara internal oleh PDO saat panggilan terakhir ke fetch() gagal karena tidak ada lagi hasil. PDO kemudian puas bahwa hasilnya diambil sepenuhnya, dan dapat membersihkan sumber daya internal apa pun antara php dan db yang dibuat untuk kumpulan hasil itu, memungkinkan Anda membuat/mengambil kueri lain.

Ada cara lain untuk membuat PDO "panggil fetch() hingga fetch() gagal".

  1. Cukup gunakan fetchAll(), yang hanya mengambil semua baris, sehingga akan mencapai akhir set hasil.
  2. atau cukup panggil closeCursor()

*jika Anda melihat sumber untuk closeCursor(), implementasi default secara harfiah hanya mengambil baris dan membuangnya hingga mencapai akhir. Jelas ditulis dalam c, tetapi kurang lebih seperti ini:

function closeCursor() {
    while ($row = $stmt->fetch()) {}
    $this->stmtFullyFetched = true;
}

Beberapa driver db mungkin memiliki implementasi yang lebih efisien yang tidak mengharuskan mereka mengambil banyak baris yang tidak dipedulikan siapa pun, tetapi itulah cara default PDO melakukannya. Pokoknya...

Biasanya Anda tidak memiliki masalah ini saat menggunakan kueri buffered. Alasannya adalah karena dengan kueri buffer, tepat setelah Anda menjalankannya, PDO akan secara otomatis mengambil hasil db ke dalam memori php, jadi PDO melakukan bagian "panggilan fetch() hingga fetch() gagal" untuk Anda, secara otomatis. Saat nanti Anda memanggil fetch() atau fetchAll() sendiri, itu mengambil hasil dari memori php, bukan dari db. Jadi pada dasarnya, kumpulan hasil segera diambil sepenuhnya saat menggunakan kueri buffered, jadi tidak ada peluang untuk memiliki lebih dari 1 "set hasil yang sedang diambil" pada saat yang sama (karena php adalah utas tunggal, jadi tidak ada peluang untuk 2 kueri berjalan pada waktu yang sama).

Mengingat ini:

$sql = "select * from test.a limit 1";
$stmt = $dbh->prepare($sql);
$stmt->execute(array());

Cara untuk mengambil set hasil sepenuhnya (dengan asumsi Anda hanya menginginkan baris pertama):

$row = $stmt->fetch();
$stmt->closeCursor();

atau

list($row) = $stmt->fetchAll(); //tricky

atau

$row = $stmt->fetch();
while ($stmt->fetch()) {}


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. konversi karakter utf8mb4 ke utf8 di php

  2. Mengambil MySQL dengan Kivy

  3. Cara mematikan mode ketat MySQL di Rails

  4. Pengindeksan untuk pagination keyset di mysql

  5. Apa cara terbaik untuk memigrasikan Django DB dari SQLite ke MySQL?