PDO ile satır sayısı


192

Çevresinde birçok çelişkili ifade var. PHP PDO kullanarak satır sayısı için en iyi yolu nedir? PDO kullanmadan önce, sadece kullandım mysql_num_rows.

fetchAll istemeyeceğim bir şey çünkü bazen büyük veri kümeleriyle uğraşıyor olabilirim, bu yüzden kullanımım için iyi değil.

Önerin var mı?

Yanıtlar:


265
$sql = "SELECT count(*) FROM `table` WHERE foo = ?"; 
$result = $con->prepare($sql); 
$result->execute([$bar]); 
$number_of_rows = $result->fetchColumn(); 

Bunu yapmanın en zarif yolu değil, ayrıca ekstra bir sorgu içerir.

PDO sahiptir PDOStatement::rowCount()görünüşte gelmez, hangi değil MySql çalışır. Ne acı.

PDO Dokümanından:

Çoğu veritabanında PDOStatement :: rowCount (), bir SELECT ifadesinden etkilenen satır sayısını döndürmez. Bunun yerine, amaçlanan SELECT ifadesiyle aynı tahminlere sahip bir SELECT COUNT (*) ifadesi vermek için PDO :: query () kullanın, ardından döndürülecek satır sayısını almak için PDOStatement :: fetchColumn () kullanın. Ardından uygulamanız doğru eylemi gerçekleştirebilir.

DÜZENLEME: Yukarıdaki kod örneği, çoğu durumda satır sayma amacıyla gereksiz olan hazırlanmış bir ifade kullanır, bu nedenle:

$nRows = $pdo->query('select count(*) from blah')->fetchColumn(); 
echo $nRows;

bu ekstra bir veritabanı sorgusu yapmak anlamına gelir. Zaten bir seçme sorgusu yaptığını ve şimdi kaç satır döndürüldüğünü bilmek istediğini varsayıyorum.
nickf

1
nickf doğrudur. PDO kullanırken mysql_num_rows () işe yaramaz mı?
James

Doğru, görünüşe göre PDOStatement :: rowCount () var ama bu MySql'de çalışmıyor
karim79

11
Bu yaklaşımı kullanarak, fetchColumn()"1234" dizesini döndürür ... EDIT'iniz echo count($nRows);- count()bir dizi fonksiyonudur: P. Ayrıca sonucu fetchColumn()bir tamsayıya döküm türü öneririm . $count = (int) $stmt->fetchColumn()
Cobby

1
@ karim79 Hazırlanmayan deyim yaklaşımı yalnızca gerçek satır sayısı yerine 1 döndürüyor. Hazırlanan ifade iyi çalışıyor. Sorun ne olabilir?
SilentAssassin

86

Daha önce benzer bir sorunun cevabında yazdığım gibi , çalışmanın tek nedeni mysql_num_rows(), size bu bilgileri vermemiş olsanız bile, bu bilgileri vermek için tüm satırları dahili olarak getirmesiydi.

PDO'da seçenekleriniz:

  1. MySQL FOUND_ROWS()işlevini kullanın .
  2. fetchAll()Tüm satırları bir diziye getirmek için PDO işlevini kullanın , ardından count()bunu kullanın .
  3. SELECT COUNT(*)Karim79'un önerdiği gibi, fazladan bir sorgu yapın .

8
Beni mysql_num_rows () hakkında daha fazla eğittiğiniz için teşekkür ederim, kendime verdiğim önemli bir darboğaz olabilir gibi görünüyor. Tekrar teşekkürler.
James

2
fetch_all aslında fetchAll () :)
dinamik

2
Sonuç büyükse 2. Seçenek önerilmez.
Edson Horacio Junior

FOUND_ROWS (), MySQL'den kaldırılacaktır, bu nedenle, eğer zaten aşina iseniz, bunu kullanmadan önce lütfen FOUND_ROWS bağlantısını kontrol edin.
anatak

29

Sık sık olduğu gibi, bu soru cehennem gibi kafa karıştırıcı. İnsanlar buraya iki farklı görev düşünerek geliyorlar :

  1. Tabloda kaç satır olduğunu bilmeleri gerekir
  2. Bir sorgunun herhangi bir satır döndürüp döndürmediğini bilmeleri gerekir

Bu, ortak hiçbir şeyi olmayan ve aynı işlevle çözülemeyen iki farklı görevdir. İronik olarak, ikisi için gerçek PDOStatement::rowCount()işlev kullanılmamalıdır.

Bakalım neden

Tablodaki satırları sayma

PDO kullanmadan önce sadece kullandım mysql_num_rows().

Bunu zaten yanlış yaptığınızı gösterir. Tablodaki satır sayısını saymak için mysql_num_rows()veya kullanmak , sunucu kaynaklarını tüketmek açısından gerçek bir felakettir . Bir veritabanının diskteki tüm satırları okuması, veritabanı sunucusundaki belleği tüketmesi ve ardından tüm bu veri yığınını PHP'ye göndermesi, PHP işleminin hafızasını da tüketmesi ve sunucunuzu mutlak bir sebep olmadan yüklemesi gerekir. Ayrıca, satırları yalnızca saymak için seçmek mantıklı değildir. Bunun yerine bir sorgu çalıştırılmalıdır. Veritabanı , gerçek satırları okumadan ve yalnızca bir satır döndürmeden kayıtları dizinden sayar .rowCount()
count(*)

Bu amaçla, kabul edilen cevapta önerilen kod adildir.

Döndürülen sayı satırlarını sayma.

İkinci kullanım durumu, anlamsız olduğu kadar felaket değildir: sorgunuzun herhangi bir veri döndürüp döndürmediğini bilmeniz gerekiyorsa, her zaman verileriniz vardır!

Diyelim ki, yalnızca bir satır seçiyorsanız. Tamam, getirilen satırı bayrak olarak kullanabilirsiniz:

$stmt->execute();
$row = $stmt->fetch();
if (!$row) { // here! as simple as that
    echo 'No data found';
}

Çok sayıda satır almanız gerekirse, kullanabilirsiniz fetchAll().

fetchAll() bazen büyük veri kümeleriyle uğraşabileceğim için istemeyeceğim bir şey

Evet, ilk kullanım durumunda iki kat daha kötü olurdu. Daha önce öğrenmiş gibi, sadece yok olan ne, bunları saymak için yalnızca satırları seçin rowCount()ne de fetchAll().

Ancak, seçilen satırları gerçekten kullanacaksanız, kullanımda yanlış bir şey yoktur fetchAll(). Bir web uygulamasında asla büyük miktarda satır seçmemeniz gerektiğini unutmayın. Aslında bir web sayfasında kullanılacak Sadece satırlar dolayısıyla kullanım lazım, seçilmelidir LIMIT, WHEREya da SQL benzer bir fıkra. Ve böylesine ılımlı miktarda veri için her şey yolunda fetchAll(). Ve tekrar, bu fonksiyonun sonucunu şu durumda kullanın:

$stmt->execute();
$data = $stmt->fetchAll();
if (!$data) { // again, no rowCount() is needed!
    echo 'No data found';
}

Ve elbette , diğer iki sorgunun en üstteki iki yanıtta önerildiği gibi herhangi bir satır döndürüp döndürmediğini söylemek için fazladan bir sorgu çalıştırmak mutlak delilik olacaktır .

Büyük bir sonuç kümesindeki satır sayısını sayma

Böyle nadir bir durumda, çok büyük miktarda satır seçmeniz gerektiğinde (örneğin bir konsol uygulamasında), kullanılan bellek miktarını azaltmak için arabelleksiz bir sorgu kullanmanız gerekir . Ancak bu rowCount() mevcut olmadığında gerçek durumdur , bu nedenle bu işlev için de bir faydası yoktur.

Bu nedenle, seçilen satır sayısı için yakın bir tahmin bilmeniz gerektiğinde, fazladan bir sorgu çalıştırmanız gerekebileceği tek kullanım durumudur.


API'nın bir arama sorgusunun toplam sonuçlarını yazdırması gerekiyorsa yararlıdır. size yalnızca 10 veya 15 satır verir, ancak toplam 284 sonuç olduğunu da söylemelidir.
Andres SK

4
@andufo Öyle değil. Lütfen unutmayın: bir geliştirici bunu asla böyle yapmamalıdır . Arama sorgusu hiçbir zaman 284 satırı döndürmemelidir. Göstermek için 15 döndürülmeli ve 284 bulunduğunu belirtmek için ayrı sorgudan bir satır döndürülmelidir .
Ortak Duygunuz

2
Bu çok iyi bir nokta - başlangıçta sezgisel değil, ama geçerli. Çoğu insan iki basit bir SQL sorguları unutmak yolu daha hızlı biraz daha büyük bir olandan. Herhangi bir saymayı haklı çıkarmak için, optimize edilemeyen ve muhtemelen birkaç sonuç getirecek çok yavaş bir sorguya sahip olmanız gerekir. Bunu işaret ettiğiniz için teşekkürler!
PeerBr

@ Common Sense: Emin olun: sonuç kümesi çok büyükse fetchAll () kötü bir fikir olmaz mı? Verileri art arda almak için fetch () yöntemini kullanmak daha iyi olmaz mıydı?
timmornYE

@timmornYE Bu, cevabımın son paragrafında söylenen şeydir
Ortak

21

Bu çok geç, ama problemle karşılaştım ve bunu yapıyorum:

function countAll($table){
   $dbh = dbConnect();
   $sql = "select * from `$table`";

   $stmt = $dbh->prepare($sql);
    try { $stmt->execute();}
    catch(PDOException $e){echo $e->getMessage();}

return $stmt->rowCount();

Gerçekten basit ve kolaydır. :)


19
Tüm verileri yalnızca saymak için seçmek, veritabanı etkileşiminin en temel kurallarına aykırıdır.
Yaygın

Belki de döndürülen tüm değerler için bir ilerleme çubuğuna sahip olmak istersiniz, bu yüzden önceden satır sayısını bilmeniz gerekir.
Jonny

18

Bunu kullanarak sona erdi:

$result = $db->query($query)->fetchAll();

if (count($result) > 0) {
    foreach ($result as $row) {
        echo $row['blah'] . '<br />';
    }
} else {
    echo "<p>Nothing matched your query.</p>";
}

12

Bu yazı eski ama PDO ile php satır sayısı alma basit

$stmt = $db->query('SELECT * FROM table');
$row_count = $stmt->rowCount();

3
Karim79'un cevabında belirtilen belgelere bakın. Bu bazen işe yarar, ancak güvenilir değildir.
öğleden sonra

5

Bu eski bir gönderi, ancak alternatifler aramaktan sinirleniyor. PDO'nun özellikle PHP ve MySQL'in el ele gitme eğilimi göstermesi nedeniyle bu özelliğe sahip olmaması çok talihsiz bir durum.

FetchColumn () kullanıldığında talihsiz bir kusur var, çünkü fetchColumn () iğneyi bir sonraki satıra hareket ettirdikçe bu sonuç kümesini (etkin olarak) artık kullanamazsınız. Örneğin, benzer bir sonucunuz varsa

  1. Meyve-> Muz
  2. Meyve-> Apple
  3. Meyve-> Turuncu

FetchColumn () kullanırsanız, döndürülen 3 meyve olduğunu öğrenebilirsiniz, ancak şimdi sonuçta döngü yaparsanız, yalnızca iki sütununuz vardır, fetchColumn () 'un fiyatı, yalnızca bulmak için sonuçların ilk sütununun kaybıdır kaç satır döndürüldüğünü gösterir. Bu, özensiz kodlamaya yol açar ve uygulandığında tamamen hataya neden olan sonuçlara yol açar.

Yani, fetchColumn () kullanarak sadece yeni bir çalışma sonuç kümesi almak için tamamen yeni çağrı ve MySQL sorgusu uygulamak ve uygulamak zorunda. (umarım son sorgunuzdan bu yana değişmemiştir), biliyorum, ama olası değil. Ayrıca, tüm satırlardaki çift sorguların yükü doğrulamayı sayar. Bu örnek için küçüktür, ancak 2 milyon satırı birleştirilmiş sorguda ayrıştırmak, hoş bir fiyat ödemek için değil.

PHP'yi seviyorum ve geliştirilmesine dahil olan herkesi ve genel olarak PHP'yi günlük olarak kullanarak destekliyorum, ancak bunun gelecekteki sürümlerde ele alınacağını umuyorum. Bu 'gerçekten' PHP PDO ile benim tek şikayet, aksi takdirde büyük bir sınıftır.


2

Bunu cevaplıyorum çünkü şimdi bunu bilerek kendimi tuzağa düşürdüm ve belki de faydalı olacaktır.

Sonuçları iki kez getiremeyeceğinizi unutmayın. Getirme sonucunu diziye kaydetmeli, satır sayısını almalı count($array)ve sonuçları çıktısıyla almalısınız foreach. Örneğin:

$query = "your_query_here";
$STH = $DBH->prepare($query);
$STH->execute();
$rows = $STH->fetchAll();
//all your results is in $rows array
$STH->setFetchMode(PDO::FETCH_ASSOC);           
if (count($rows) > 0) {             
    foreach ($rows as $row) {
        //output your rows
    }                       
}

1

Sadece bir satır sayısı (veri değil) almak istiyorsanız yani. hazırlanmış bir ifadede COUNT (*) kullanarak, yapmanız gereken tek şey sonucu almak ve değeri okumaktır:

$sql = "SELECT count(*) FROM `table` WHERE foo = bar";
$statement = $con->prepare($sql); 
$statement->execute(); 
$count = $statement->fetch(PDO::FETCH_NUM); // Return array indexed by column number
return reset($count); // Resets array cursor and returns first value (the count)

Aslında basit bir sayım gerçekleştirmek için tüm satırları (veri) almak kaynak israfıdır. Sonuç kümesi büyükse sunucunuz bunu boğabilir.



1

Bir sorgudaki değişkenleri kullanmak için bindValue()veya öğesini kullanmanız gerekir bindParam(). Ve yok değişkenleri bitiştirmek" . $variable . "

$statement = "SELECT count(account_id) FROM account
                  WHERE email = ? AND is_email_confirmed;";
$preparedStatement = $this->postgreSqlHandler->prepare($statement);
$preparedStatement->bindValue(1, $account->getEmail());
$preparedStatement->execute();
$numberRows= $preparedStatement->fetchColumn();

GL


0

O meselesi olduğunda saymak nasıl mysql veya PHP PDO ile tablodaki kaç satır olsun bunu kullanmak

// count total number of rows
$query = "SELECT COUNT(*) as total_rows FROM sometable";
$stmt = $con->prepare($query);

// execute query
$stmt->execute();

// get total rows
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$total_rows = $row['total_rows'];

kredileri Mike'a gidiyor @ codeofaninja.com


-1

İlk girişi geri almak için hızlı bir astar. Bu çok temel sorgular için güzel.

<?php
$count = current($db->query("select count(*) from table")->fetch());
?>

Referans


-1

$count = $stmt->rowCount();Oracle 11.2 ile denedim ve işe yaramadı. Aşağıda gösterildiği gibi bir for döngüsü kullanmaya karar verdim.

   $count =  "";
    $stmt =  $conn->prepare($sql);
    $stmt->execute();
   echo "<table border='1'>\n";
   while($row = $stmt->fetch(PDO::FETCH_OBJ)) {
        $count++;
        echo "<tr>\n";
    foreach ($row as $item) {
    echo "<td class='td2'>".($item !== null ? htmlentities($item, ENT_QUOTES):"&nbsp;")."</td>\n";
        } //foreach ends
        }// while ends
        echo "</table>\n";
       //echo " no of rows : ". oci_num_rows($stmt);
       //equivalent in pdo::prepare statement
       echo "no.of rows :".$count;

-1

Belirli bir satır istiyorum ve bulunup bulunmadığını bilmek istiyorum düz sorgular için, gibi bir şey kullanın:

function fetchSpecificRow(&$myRecord) {
    $myRecord = array();
    $myQuery = "some sql...";
    $stmt = $this->prepare($myQuery);
    $stmt->execute(array($parm1, $parm2, ...));
    if ($myRecord = $stmt->fetch(PDO::FETCH_ASSOC)) return 0;
    return $myErrNum;
}

-1

Basit bir çözüm var. DB'nize PDO bağlantısı kullanıyorsanız aşağıdaki gibi:

try {
    $handler = new PDO('mysql:host=localhost;dbname=name_of_your_db', 'your_login', 'your_password'); 
    $handler -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} 
    catch (PDOException $e) {   
    echo $e->getMessage();
}

Ardından, DB sorgusu:

$query = $handler->query("SELECT id FROM your_table WHERE ...");

Ve son olarak, sorgunuzla eşleşen satırları saymak için şöyle yazın

$amountOfRows = $query->rowcount();

Neden bu beni çoğu zaman -1 döndürüyor? Veri olsa bile. .
Ingus

-1

fetchColumn ()

rekor sayı almak istiyorsanız kullanılır [effisien]

$sql   = "SELECT COUNT(*) FROM fruit WHERE calories > 100";
$res   = $conn->query($sql);
$count = $res->fetchColumn(); // ex = 2

sorgu()

veri ve kayıt sayısını almak istiyorsanız kullanılır [seçenekler]

$sql = "SELECT * FROM fruit WHERE calories > 100";
$res = $conn->query($sql);

if ( $res->rowCount() > 0) {

    foreach ( $res as $row ) {
        print "Name: {$row['NAME']} <br />";
    }

}
else {
    print "No rows matched the query.";
}

PDOStatement :: rowCount


Bunu asla yapmamalısın . Az ya da çok büyük bir masada tüm sunucuların hafızasını yiyip sunucuyu
Sizin Common Sense

Şimdi cevabınız sadece bir düzine mevcut cevabı çoğaltır.
Ortak

-2

mysql ifadenizdeki gibi bir COUNT (*) yaptığınızda

$q = $db->query("SELECT COUNT(*) FROM ...");

mysql sorgunuz zaten neden tekrar php sayma sonuç sayısını sayıyor? MySQL'in sonucunu almak için

$q = $db->query("SELECT COUNT(*) as counted FROM ...");
$nb = $q->fetch(PDO::FETCH_OBJ);
$nb = $nb->counted;

ve $nbmysql ifadenizle saydığınız tamsayıyı yazmak için biraz uzun ama yürütülmesi hızlı

Düzenleme: yanlış yazı için üzgünüm ama bazı örnek olarak sayım ile sorgu göster, mysql sonucu kullanmanızı öneriyordu, ancak sayıyı sql fetchAll () kullanmıyorsanız verimli, eğer bir değişkene sonuç kaydederseniz çizgiyi kaybetmeyeceksin.

$data = $dbh->query("SELECT * FROM ...");
$table = $data->fetchAll(PDO::FETCH_OBJ);

count($table)satır sayısını döndürür ve sonucu beğendikten $row = $table[0] veya kullandıktan sonra kullanmaya devam edebilirsiniz.foreach

foreach($table as $row){
  print $row->id;
}

1
Soru, mysql ekstrenizde bir COUNT (*) YAPMADIĞINIZda nasıl sayılacağınızdır
Ortak Duygunuz

-2

Burada, PDO sınıfının, son sorgunun "WHERE" ölçütlerine dahil edilen satır sayısını almak için yardımcı bir işlev içeren, özel olarak hazırlanmış bir uzantı var.

Bununla birlikte, hangi komutları kullandığınıza bağlı olarak daha fazla 'işleyici' eklemeniz gerekebilir. Şu anda yalnızca "FROM" veya "UPDATE" kullanan sorgular için çalışıyor.

class PDO_V extends PDO
{
    private $lastQuery = null;

    public function query($query)
    {
        $this->lastQuery = $query;    
        return parent::query($query);
    }
    public function getLastQueryRowCount()
    {
        $lastQuery = $this->lastQuery;
        $commandBeforeTableName = null;
        if (strpos($lastQuery, 'FROM') !== false)
            $commandBeforeTableName = 'FROM';
        if (strpos($lastQuery, 'UPDATE') !== false)
            $commandBeforeTableName = 'UPDATE';

        $after = substr($lastQuery, strpos($lastQuery, $commandBeforeTableName) + (strlen($commandBeforeTableName) + 1));
        $table = substr($after, 0, strpos($after, ' '));

        $wherePart = substr($lastQuery, strpos($lastQuery, 'WHERE'));

        $result = parent::query("SELECT COUNT(*) FROM $table " . $wherePart);
        if ($result == null)
            return 0;
        return $result->fetchColumn();
    }
}

Sorun çabaya değmez. Böyle bir sayı o kadar nadiren ihtiyaç duyulur ki, kişinin özel bir uzantıya ihtiyacı yoktur. Bahsetmemek gerekirse hazırlanan ifadeleri desteklemiyor - PDO'yu kullanmanın tek nedeni.
Ortak Duygunuz

-2

En iyi yöntemi bir satırda veya işlevde birleştirebilir ve yeni sorgunun sizin için otomatik olarak oluşturulmasını sağlayabilirsiniz:

function getRowCount($q){ 
    global $db;
    return $db->query(preg_replace('/SELECT [A-Za-z,]+ FROM /i','SELECT count(*) FROM ',$q))->fetchColumn();
}

$numRows = getRowCount($query);

Bu yöntemde iyi bir şey yok. Sadece kaç satır döndürüldüğünü bilmek için fazladan bir sorgu çalıştırmak kesinlikle mantıklı değildir.
Ortak

-2
<table>
      <thead>
           <tr>
                <th>Sn.</th>
                <th>Name</th>
           </tr>
      </thead>
      <tbody>
<?php
     $i=0;
     $statement = $db->prepare("SELECT * FROM tbl_user ORDER BY name ASC");
     $statement->execute();
     $result = $statement->fetchColumn();
     foreach($result as $row) {
        $i++;
    ?>  
      <tr>
         <td><?php echo $i; ?></td>
         <td><?php echo $row['name']; ?></td>
      </tr>
     <?php
          }
     ?>
     </tbody>
</table>

1
Bu gerçekten kötü bir fikir. Tüm satırları seçmek, büyük bir bant genişliği kaybıdır.
Nafees

-2
function count_x($connect) {  
 $query = "  SELECT * FROM tbl WHERE id = '0' ";  
 $statement = $connect->prepare($query);  $statement->execute();  
 $total_rows = $statement->rowCount();  
 return $total_rows; 
}

-4

Parametre kullan array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL), aksi takdirde -1 göster:

Usen Parametro array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL), Sin Ello Satış -1

misal:

$res1 = $mdb2->prepare("SELECT clave FROM $tb WHERE id_usuario='$username' AND activo=1 and id_tipo_usuario='4'", array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$res1->execute();

$count=$res1->rowCount();
echo $count;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.