Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

PDO “Uncaught exception 'PDOException' .. Không thể thực thi các truy vấn trong khi các truy vấn không có bộ đệm khác đang hoạt động. Cân nhắc sử dụng PDOStatement ::fetchAll (). ”

Bạn cần tìm nạp cho đến khi nỗ lực tìm nạp hàng không thành công. Tôi biết bạn có thể chỉ có một hàng trong tập hợp kết quả và nghĩ rằng một lần tìm nạp là đủ, nhưng không phải (khi bạn đang sử dụng các truy vấn không có bộ đệm). PDO không biết có bao nhiêu hàng cho đến khi nó kết thúc, nơi nó cố gắng tìm nạp hàng tiếp theo, nhưng nó không thành công.

Có thể bạn có các câu lệnh khác mà bạn đã không hoàn toàn "tìm nạp cho đến khi tìm nạp không thành công". Có, tôi thấy rằng bạn tìm nạp cho đến khi tìm nạp không thành công cho một nhưng điều đó không có nghĩa là bạn đã làm điều đó cho tất cả chúng.

Để làm rõ -Khi bạn thực hiện một truy vấn thông qua execute (), bạn tạo một tập kết quả phải được tìm nạp từ db vào php. PDO chỉ có thể xử lý 1 trong những "tập hợp kết quả đang được tìm nạp" này tại một thời điểm (trên mỗi kết nối). Bạn cần tìm nạp hoàn toàn tập kết quả, từ đầu đến cuối, trước khi bạn có thể bắt đầu tìm nạp tập kết quả khác từ một lệnh gọi khác để thực thi ().

Khi bạn "gọi tìm nạp () cho đến khi tìm nạp () không thành công", thực tế là bạn đã đạt đến cuối kết quả được PDO lưu ý nội bộ khi lệnh gọi tìm nạp () cuối cùng đó không thành công do không còn kết quả nào nữa. PDO sau đó hài lòng rằng kết quả đã được tìm nạp đầy đủ và nó có thể dọn dẹp bất kỳ tài nguyên nội bộ nào giữa php và db đã được thiết lập cho tập kết quả đó, cho phép bạn thực hiện / tìm nạp các truy vấn khác.

Có những cách khác để thực hiện PDO "cuộc gọi tìm nạp () cho đến khi tìm nạp () không thành công".

  1. Chỉ cần sử dụng fetchAll (), chỉ cần tìm nạp tất cả các hàng và do đó, nó sẽ ở cuối tập kết quả.
  2. hoặc chỉ gọi closeCursor ()

* nếu bạn nhìn vào nguồn cho closeCursor (), việc triển khai mặc định theo nghĩa đen chỉ tìm nạp các hàng và loại bỏ chúng cho đến khi nó kết thúc. Nó được viết bằng c rõ ràng, nhưng nó ít nhiều làm được điều này:

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

Một số trình điều khiển db có thể có cách triển khai hiệu quả hơn mà không yêu cầu họ tìm nạp nhiều hàng mà không ai quan tâm, nhưng đó là cách mặc định của PDO. Dù sao ...

Thông thường, bạn không gặp những vấn đề này khi sử dụng các truy vấn có bộ đệm. Lý do là vì với các truy vấn được đệm, ngay sau khi bạn thực thi chúng, PDO sẽ tự động tìm nạp đầy đủ các kết quả db vào bộ nhớ php, vì vậy nó sẽ tự động thực hiện phần "call fetch () cho đến khi một fetch () fail" cho bạn. Sau đó, khi bạn tự gọi fetch () hoặc fetchAll (), nó đang tìm nạp kết quả từ bộ nhớ php, không phải từ db. Vì vậy, về cơ bản, tập kết quả được tìm nạp đầy đủ ngay lập tức khi sử dụng truy vấn có bộ đệm, vì vậy không có cơ hội để có nhiều hơn 1 "tập kết quả đang được tìm nạp" cùng một lúc (vì php là một luồng đơn, vì vậy không có cơ hội có 2 truy vấn chạy đồng thời).

Đưa ra điều này:

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

Các cách để tìm nạp đầy đủ tập kết quả (giả sử bạn chỉ muốn hàng đầu tiên):

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

hoặc

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

hoặc

$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. Cơ sở dữ liệu SQL với số cột thay đổi

  2. Làm thế nào để chuyển đổi mssql script sang mysql

  3. Cách thay đổi cổng MySQL / MariaDB mặc định trong Linux

  4. SQLite và đặt hàng tùy chỉnh bởi

  5. Truy vấn tổng hợp MySQL