Jak to często bywa, pytanie to jest mylące jak diabli. Ludzie przyjeżdżają tutaj z myślą o dwóch różnych zadaniach :
- Muszą wiedzieć, ile wierszy w tabeli
- Muszą wiedzieć, czy zapytanie zwróciło jakieś wiersze
To dwa absolutnie różne zadania, które nie mają ze sobą nic wspólnego i nie mogą być rozwiązane przez tę samą funkcję. Jak na ironię, dla żadnej z nichPDOStatement::rowCount()
nie trzeba używać faktycznej funkcji.
Zobaczmy dlaczego
Zliczanie wierszy w tabeli
Przed użyciem PDO po prostu użyłem mysql_num_rows()
.
Oznacza to, że już źle to zrobiłeś. Użycie mysql_num_rows()
lub rowCount()
do zliczenia liczby wierszy w tabeli jest prawdziwą katastrofą pod względem zużycia zasobów serwera. Baza danych musi odczytać wszystkie wiersze z dysku, zużyć pamięć na serwerze bazy danych, a następnie wysłać całą tę stertę danych do PHP, zużywając również pamięć procesu PHP, obciążając serwer bez absolutnie żadnego powodu.
Poza tym wybieranie wierszy tylko do ich policzenia po prostu nie ma sensu. count(*)
Zapytania ma być uruchamiany zamiast. Baza danych zliczy rekordy z indeksu, bez odczytywania rzeczywistych wierszy, a następnie zwrócony zostanie tylko jeden wiersz.
W tym celu kod sugerowany w zaakceptowanej odpowiedzi jest sprawiedliwy.
Zliczanie zwracanych wierszy.
Drugi przypadek użycia nie jest tak katastrofalny jak raczej bezcelowy: jeśli chcesz wiedzieć, czy zapytanie zwróciło jakieś dane, zawsze masz same dane!
Powiedz, jeśli wybierasz tylko jeden wiersz. W porządku, możesz użyć pobranego wiersza jako flagi:
$stmt->execute();
$row = $stmt->fetch();
if (!$row) { // here! as simple as that
echo 'No data found';
}
Jeśli potrzebujesz wielu wierszy, możesz użyć fetchAll()
.
fetchAll()
to coś, czego nie chcę, ponieważ czasami mam do czynienia z dużymi zestawami danych
Tak, oczywiście, w pierwszym przypadku użycia będzie dwa razy gorszy. Ale jak już się nauczyliśmy, po prostu nie zaznaczaj wierszy, aby je policzyć, ani z rowCount()
ani fetchAll()
.
Ale jeśli rzeczywiście zamierzasz użyć wybranych wierszy, nie ma nic złego w użyciu fetchAll()
. Pamiętaj, że w aplikacji internetowej nigdy nie należy wybierać dużej liczby wierszy. Tylko wiersze, które będą rzeczywiście wykorzystywane na stronie internetowej powinny być wybierane, stąd masz do wykorzystania LIMIT
, WHERE
lub podobna klauzula w SQL. A w przypadku tak umiarkowanej ilości danych można z niego korzystać fetchAll()
. I ponownie, po prostu użyj wyniku tej funkcji pod warunkiem:
$stmt->execute();
$data = $stmt->fetchAll();
if (!$data) { // again, no rowCount() is needed!
echo 'No data found';
}
I oczywiście absolutnym szaleństwem będzie uruchomienie dodatkowego zapytania tylko po to, aby stwierdzić, czy drugie zapytanie zwróciło jakieś wiersze, jak sugeruje to w dwóch najważniejszych odpowiedziach.
Zliczanie liczby wierszy w dużym zestawie wyników
W tak rzadkim przypadku, gdy trzeba wybrać naprawdę ogromną liczbę wierszy (na przykład w aplikacji konsolowej), musisz użyć niebuforowanego zapytania , aby zmniejszyć ilość używanej pamięci. Ale to jest rzeczywisty przypadek, kiedy rowCount()
nie będzie dostępny , więc nie ma również zastosowania dla tej funkcji.
Dlatego jest to jedyny przypadek użycia, w którym może być konieczne uruchomienie dodatkowego zapytania, na wypadek, gdybyś musiał znać dokładne oszacowanie liczby wybranych wierszy.