2012-07-20 18 views
9

He seguido una serie de ejemplos diferentes sobre el uso de un SELECT en una declaración preparada, pero no se devuelve nada. EDITAR he cambiado mi código un poco para tener este aspecto:Problemas para ejecutar una consulta SELECT en una declaración preparada

$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(); 

Ahora todas las entradas deseadas, a excepción de la primera, se añaden a $ fila []. ¿Por qué no se agrega la primera entrada? ¡Gracias de antemano!

+0

Se utiliza * en su consulta , pero $ row en tu bind_result ($ row). bind_result debería contener columnas, creo. Lea más aquí: http://nl3.php.net/manual/en/mysqli-stmt.bind-result.php Entonces su variable $ row contiene la primera columna de lo que sea * significa. (Evite * en todas sus consultas, pero esa es una cuestión diferente.) –

Respuesta

17

EDITAR 07/2015 (pregunta ha sido editada desde la respuesta original, pero los principios subyacentes son los mismos)

NuncaSELECT * en un entorno de producción, sólo se va a volver a morder en extraño, impredecible y formas aparentemente sin relación. Al especificar las columnas que desea, se asegurará de que el orden de las columnas, el tipo de datos, la restricción y todo tipo de otros elementos no le causen problemas a largo plazo.

Esta respuesta sigue siendo válida en su mayoría, así que la dejo aquí tal como está, pero la principal para llevar es: use PDO, hace el 98% de las cosas que siempre necesitará con un contenido mucho más limpio y más API sucinta sobre el mismo back-end. Si necesita una API específica de RDBMS más compleja, ya comprenderá los problemas que tiene y por qué necesita mysqli, etc. en su lugar.


SELECT * no funciona muy bien con MySQLi comandos preparados. Es una de las principales razones por las que recomiendo PDO en su lugar, eso y el ridículo requisito de vincular referencias variables en lugar de valores a los parámetros.

$stmt->bind_result($row); 

Esto no es vinculante para la fila de resultados a una variable, que sólo sería vinculante para una sola columna. Y como usaste SELECT *, no hace lo que quieres.

Si desea utilizar MySQLi sobre DOP (que, como digo, yo recomendaría) hay algunos buenos ejemplos de cómo SELECT * en los comentarios como this one en la página del manual bind_result().

o simplemente puede especificar las columnas que desea recuperar:

$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(); 

EDITAR basado en su nuevo código, que debería estar haciendo esto:

// $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

Gracias por su respuesta. Hice un poco de progreso, pero revisa mi edición para el siguiente número. – Glenncito

+0

@Glenncito Ver la edición anterior – DaveRandom

+0

También estoy luchando con esto, hacer una declaración preparada selectiva simplemente no funcionará, ¿qué terminaste haciendo exactamente al final? –

3

pienso debe enlazar a las columnas en bind_results() como

/* 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); 
} 

Aquí $ col1 y $ une col2 para codificar y columnas Nombre de tabla País

(En lugar de * SELECCIONAR utilizar los nombres de columna)

Además referencia: http://php.net/manual/en/mysqli-stmt.bind-result.php

+0

Gracias por su respuesta. Hice un poco de progreso, pero revisa mi edición para el siguiente número. – Glenncito

Cuestiones relacionadas