2012-07-20 13 views
9

Ive zastosował kilka różnych przykładów dotyczących użycia SELECT w przygotowanej instrukcji, ale nic nie jest zwracane. EDIT I zmieniły mojego kodu trochę wyglądać następująco:Masz problemy z wykonaniem zapytania SELECT w przygotowanym oświadczeniu

$date1 = 2012-01-01; 
$date2 = 2012-01-31; 
$sql_con = new mysqli('db', 'username', 'password', 'database'); 

if($stmt = $sql_con->prepare("SELECT eventLogID FROM Country WHERE countryCode=? AND date BETWEEN ? AND ?")){ 

    $stmt->bind_param("sss", $country_code, $date1,$date2); 

    $stmt->execute(); 

    $i=0; 
    while ($stmt->fetch()){ 
    $stmt->bind_result($row[$i]); 
    $i++; 
    } 

    $stmt->close(); 
$sql_con->close(); 

Teraz wszystkie żądane pozycje, z wyjątkiem pierwszego, są dodawane do $ row []. Dlaczego nie jest dodawany pierwszy wpis? Z góry dziękuję!

+0

użyć * w zapytaniu , ale $ rząd w twoim bind_result ($ row). bind_result powinien zawierać kolumny, które myślę. Przeczytaj więcej tutaj: http://nl3.php.net/manual/en/mysqli-stmt.bind-result.php Więc twoja zmienna $ row zawiera pierwszą kolumnę tego, czym jest * oznacza. (Unikaj * we wszystkich zapytaniach, ale to już inna sprawa). –

Odpowiedz

17

EDIT 07/2015 (kwestia została edytowana od oryginalnej odpowiedzi, ale podstawowe zasady są takie same)

NigdySELECT * w środowisku produkcyjnym, będzie pochodzić wyłącznie z powrotem do ugryzie cię w dziwne, nieprzewidywalne i pozornie niepowiązanych ze sobą sposobów. Określając kolumny, które chcesz, będziesz mieć pewność, że kolejność kolumn, typ danych, ograniczenia i wszelkiego rodzaju inne elementy nie spowodują problemów na dłuższą metę.

Ta odpowiedź jest nadal ważna, dlatego zostawiam ją tutaj tak, jak jest, ale głównym wyjściem jest: użyj PDO, to 98% rzeczy, których będziesz potrzebować, o wiele czystsze i więcej zwięzłe API na tym samym zapleczu. Jeśli potrzebujesz bardziej złożonego API specyficznego dla RDBMS, zrozumiesz już problemy, które masz i dlaczego potrzebujesz mysqli itp.


SELECT * nie bardzo dobrze przygotowane sprawozdanie z MySQLi pracować. Jest to jeden z głównych powodów, dla których polecam PDO - ten i niedorzeczny wymóg wiązania zmiennych referencji zamiast wartości do parametrów.

$stmt->bind_result($row); 

nie wiąże się z efektem wiersz zmiennej, to będzie tylko wiązania pojedynczej kolumny. A ponieważ użyłeś SELECT *, nie robi to, czego chcesz.

Jeśli chcesz korzystać MySQLi nad PDO (które, jak mówię, polecam) istnieje kilka dobrych przykładów, w jaki sposób SELECT * w komentarzach jak this one na bind_result() dokumencie.

Albo można po prostu określić kolumny, które chcesz odzyskać:

$sql_con = new mysqli('db', 'username', 'password', 'database'); 

if($stmt = $sql_con->prepare("SELECT name, countryCode FROM Country WHERE countryCode = ?")) { 

    $stmt->bind_param("s", $country_code); 
    $stmt->execute(); 
    $stmt->bind_result($name, $countryCode); 

    while ($stmt->fetch()) { 
    // Because $name and $countryCode are passed by reference, their value 
    // changes on every iteration to reflect the current row 
    echo "<pre>"; 
    echo "name: $name\n"; 
    echo "countryCode: $countryCode\n"; 
    echo "</pre>"; 
    } 

    $stmt->close(); 

EDIT oparty na nowym kodzie, należy robić to:

// $date1 will be int(2010), $date2 will be int(1980) because you didn't 
// quote the strings! 
//$date1 = 2012-01-01; 
//$date2 = 2012-01-31; 

// Connect to DB 
$sql_con = new mysqli('db', 'username', 'password', 'database'); 

// Check for connection errors here! 

// The query we want to execute 
$sql = " 
    SELECT eventLogID 
    FROM Country 
    WHERE countryCode = ? 
    AND date BETWEEN ? AND ? 
"; 

// Attempt to prepare the query 
if ($stmt = $sql_con->prepare($sql)) { 

    // Pass the parameters 
    $date1 = '2012-01-01'; 
    $date2 = '2012-01-31'; 
    $stmt->bind_param("sss", $country_code, $date1, $date2); 

    // Execute the query 
    $stmt->execute(); 
    if (!$stmt->errno) { 
    // Handle error here 
    } 

    // Pass a variable to hold the result 
    // Remember you are binding a *column*, not a row 
    $stmt->bind_result($eventLogID); 

    // Loop the results and fetch into an array 
    $logIds = array(); 
    while ($stmt->fetch()) { 
    $logIds[] = $eventLogID; 
    } 

    // Tidy up 
    $stmt->close(); 
    $sql_con->close(); 

    // Do something with the results 
    print_r($logIds); 

} else { 
    // Handle error here 
} 
+0

Dziękuję za odpowiedź. Zrobiłem trochę postępów, ale sprawdź moją edycję kolejnego problemu. – Glenncito

+0

@Glenncito Zobacz powyżej powyżej – DaveRandom

+0

Też się z tym zmagam, robienie wybranego przygotowanego oświadczenia po prostu nie zadziała, co dokładnie skończyłeś? –

3

myślę musisz powiązać kolumny w bind_results(), jak

/* prepare statement */ 
if ($stmt = $mysqli->prepare("SELECT Code, Name FROM Country ORDER BY Name LIMIT 5")) { 
$stmt->execute(); 

/* bind variables to prepared statement */ 
$stmt->bind_result($col1, $col2); 

/* fetch values */ 
while ($stmt->fetch()) { 
    printf("%s %s\n", $col1, $col2); 
} 

Tu $ kol1 i $ COL2 wiąże się z Kodeksem i kolumny nazwa tabeli Country

(zamiast * w SELECT używać nazwy kolumn)

Dalsze odniesienia: http://php.net/manual/en/mysqli-stmt.bind-result.php

+0

Dziękuję za odpowiedź. Zrobiłem trochę postępów, ale sprawdź moją edycję kolejnego problemu. – Glenncito