Như nó thường xảy ra, câu hỏi này là khó hiểu như địa ngục. Mọi người đang đến đây có hai nhiệm vụ khác nhau trong tâm trí:
- Họ cần biết có bao nhiêu hàng trong bảng
- Họ cần biết liệu một truy vấn có trả về bất kỳ hàng nào không
Đó là hai nhiệm vụ hoàn toàn khác nhau không có điểm chung và không thể giải quyết bằng cùng một chức năng. Trớ trêu thay, đối với cả haiPDOStatement::rowCount()
chức năng thực tế phải được sử dụng.
Hãy xem tại sao
Đếm các hàng trong bảng
Trước khi sử dụng PDO tôi chỉ đơn giản là sử dụng mysql_num_rows()
.
Có nghĩa là bạn đã làm sai. Sử dụng mysql_num_rows()
hoặc rowCount()
để đếm số lượng hàng trong bảng là một thảm họa thực sự về mặt tiêu thụ tài nguyên máy chủ. Một cơ sở dữ liệu phải đọc tất cả các hàng từ đĩa, tiêu thụ bộ nhớ trên máy chủ cơ sở dữ liệu, sau đó gửi tất cả đống dữ liệu này đến PHP, cũng tiêu tốn bộ nhớ của quá trình PHP, làm gánh nặng máy chủ của bạn hoàn toàn không có lý do.
Bên cạnh đó, việc chọn các hàng chỉ để đếm chúng đơn giản là vô nghĩa. Một count(*)
truy vấn phải được chạy thay thế. Cơ sở dữ liệu sẽ đếm các bản ghi ra khỏi chỉ mục, mà không cần đọc các hàng thực tế và sau đó chỉ có một hàng được trả về.
Đối với mục đích này, mã được đề xuất trong câu trả lời được chấp nhận là công bằng.
Đếm các hàng số trả về.
Trường hợp sử dụng thứ hai không phải là thảm họa như là vô nghĩa: trong trường hợp bạn cần biết liệu truy vấn của bạn có trả lại bất kỳ dữ liệu nào không, bạn luôn có dữ liệu đó!
Nói, nếu bạn chỉ chọn một hàng. Được rồi, bạn có thể sử dụng hàng được tìm nạp làm cờ:
$stmt->execute();
$row = $stmt->fetch();
if (!$row) { // here! as simple as that
echo 'No data found';
}
Trong trường hợp bạn cần nhận được nhiều hàng, thì bạn có thể sử dụng fetchAll()
.
fetchAll()
là điều tôi sẽ không muốn vì đôi khi tôi có thể xử lý các bộ dữ liệu lớn
Tất nhiên, đối với trường hợp sử dụng đầu tiên, nó sẽ tệ gấp đôi. Nhưng như chúng ta đã biết, chỉ cần không chọn các hàng chỉ để đếm chúng, không có rowCount()
cũng không có fetchAll()
.
Nhưng trong trường hợp bạn thực sự sử dụng các hàng đã chọn, không có gì sai khi sử dụng fetchAll()
. Hãy nhớ rằng trong một ứng dụng web, bạn không bao giờ nên chọn một số lượng lớn hàng. Chỉ hàng sẽ được thực sự được sử dụng trên một trang web nên được lựa chọn, vì thế bạn phải sử dụng LIMIT
, WHERE
hoặc một điều khoản tương tự trong SQL của bạn. Và với lượng dữ liệu vừa phải như vậy, bạn hoàn toàn có quyền sử dụng fetchAll()
. Và một lần nữa, chỉ cần sử dụng kết quả của chức năng này trong điều kiện:
$stmt->execute();
$data = $stmt->fetchAll();
if (!$data) { // again, no rowCount() is needed!
echo 'No data found';
}
Và tất nhiên sẽ là điên rồ tuyệt đối khi chỉ chạy một truy vấn bổ sung để cho biết liệu truy vấn khác của bạn có trả về bất kỳ hàng nào không, như đã đề xuất trong hai câu trả lời hàng đầu.
Đếm số lượng hàng trong một tập kết quả lớn
Trong trường hợp hiếm hoi như vậy khi bạn cần chọn số lượng hàng thực sự lớn (ví dụ trong ứng dụng bảng điều khiển), bạn phải sử dụng truy vấn không có bộ đệm, để giảm lượng bộ nhớ được sử dụng. Nhưng đây là trường hợp thực tế khi rowCount()
không có sẵn , do đó cũng không sử dụng chức năng này.
Do đó, đó là trường hợp sử dụng duy nhất khi bạn có thể cần chạy một truy vấn bổ sung, trong trường hợp bạn cần biết ước tính chặt chẽ cho số lượng hàng được chọn.