2012-12-31 11 views
5

mam tej kwerendy próbki:Jak pobrać 2 razy w MySQL PDO bez fetchAll

$STH = $DBH->query("SELECT id FROM table"); 

chcę uzyskać pierwszy wiersz, a następnie pętli i wyświetli wszystkie wiersze. Więc używać następujących dostać pierwszego rzędu:

$STH->setFetchMode(PDO::FETCH_ASSOC); 
$first_row = $STH->fetch(); 
$first_row = $first_row['id']; 

używam pętli while, aby wyświetlić wszystkie wiersze znowu:

while ($list = $STH->fetch()) {  
$id = $list['id']; 
echo $id; 
} 

Teraz natomiast pomija pierwszy wiersz i chcę zostać wyświetlony. Czy istnieje odpowiednik mysql_data_seek, aby zresetować wskaźnik ponownie do pierwszego wiersza? Wiem, że można używać fetchall, ale jest źle w pamięci i marnotrawstwo. Mogę również uruchomić kwerendę i ograniczyć do 1, ale nie jest to zalecane, ponieważ mam zapytanie, które łączy wiele tabel i będzie bardzo wolne. Czy jest jakieś inne rozwiązanie?

Dzięki

Odpowiedz

5

Biorę to z powrotem wygląda można użyć contants orientacji kursora, aby wybrać wynik ... przykładowy kod nadchodzi ... Nie próbowałem tego, więc być może trzeba trochę zagrać. Jest to również oparte na założeniu, że PDO::FETCH_ORI_FIRST działa jak parametr data_seek i pozostawia kursor na pierwszej pozycji, zamiast zwracania go do tego, co było wcześniej.

$stmt = $pdo->prepare('SELECT id FROM table', array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL)); 
$stmt->execute(); 

$first = $pdo->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_FIRST); 
$first_row = $first['id']; 

// other stuff 

// first iteration we rewind to the first record; 
$cursor = PDO::FETCH_ORI_FIRST; 

while (false !== ($row = $stmt->fetch(PDO::FETCH_ASSOC, $cursor))) { 
    $id = $row['id']; 
    // successive iterations we hit the "next" record 
    $cursor = PDO::FETCH_ORI_NEXT; 
    echo $id; 
} 

nie sądzę można przewinąć oświadczenie ... Zakładając, że te bloki arent seprated przez grono pośredniczącego logicznego id po prostu to zrobić w pętli.

$STH->setFetchMode(PDO::FETCH_COLUMN); // no need to pull an array 
$count = 0; 
while ($id = $STH->fetch()) {  
    if($count === 0) { 
    $first_row = $id; 
    } 
    echo $id; 
    $count++; 
} 
+0

Potrzebuję go w tablicy, aby użyć wszystkich wierszy, a także muszę wyświetlić pierwszy wiersz przed chwilą, aby użyć go w innym celu ... dzięki :) –

+0

Cóż, wybrałeś tylko "identyfikator" w twoim przykładzie. .. – prodigitalson

+0

to tylko uproszczone zapytanie wyjaśniające problem. Zapytanie jest znacznie większe niż to, że –

1

można po prostu użyć do...while pętlę zamiast?

$STH->setFetchMode(PDO::FETCH_ASSOC); 
$list = $STH->fetch(); 
$first_id = $list['id']; 

do { 
    $id = $list['id']; 
    echo $id; 
} while ($list = $STH->fetch()); 
+0

Z jakiegoś powodu to ignoruje ORDER BY w zapytaniu ... dzięki :) –

+0

@Michael - naprawdę? Nie widzę, jak to mogłoby mieć jakikolwiek wpływ na 'order by' w zapytaniu ... –

+0

nie wiem też dlaczego tak się dzieje. Zamawiam przez desc, ale teraz wyświetla się jako rosnąco –

1

Można pobrać cały wynik, a następnie po prostu działać na nim jako tablicy. Tak więc, na przykład, można przesunąć pierwszy wynik od przodu, a następnie pętli nad wszelkimi dodatkowymi rzędami:

<?php 

$sql = "YOUR QUERY"; 
$stmt = $pdo->prepare($sql); 
$stmt->execute(); 
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC); 

// get first row 
$firstRow = array_shift($rows); 

// loop over remaining rows 
foreach ($rows as $row) { 
    // do something 
} 
+0

Myślę, że on szczególnie chciał uzyskać odpowiedź, która uniknęła przy użyciu 'fetchall' –

+0

, ale FetchALL marnuje pamięć od doświadczeń innych ... dzięki :) –

+0

@MichaelSamuel Dlaczego? Czy masz jakieś dowody na to, że 'fetchAll()' jest "złe w pamięci" i "marnotrawstwo", czy po prostu idziesz dalej, co przeczytałeś gdzie indziej? Wyobrażam sobie, że jeden 'fetchAll()' jest lepszy niż wiele 'fetch()' s. –