2011-08-16 10 views
7
$stmt = $dbh->prepare('SELECT id, name FROM folders WHERE parent_folder_id = :id'); 
$stmt->bindValue(':id', $folder_id, PDO::PARAM_INT); 

Tengo el código anterior. Si una carpeta tiene un parent_folder_id, significa que está dentro de otra carpeta. Si esta columna es NULL, significa que es una carpeta raíz.¿Cómo enlazar un valor si quiero que acepte tanto INT como NULL con PDO?

Desde mi entender, si $ folder_id es NULL entonces la tratará como 0 (por lo que no da resultados positivos con el código, ya que se debe a que el valor de esa columna es NULL y no es 0). Si cambio el tercer argumento a PDO :: PARAM_NULL, sigo sin obtener ningún resultado. Creo que esto se debe a que evalúa la consulta como "WHERE parent_folder_id = NULL" que no es igual a "WHERE parent_folder_id es NULL".

¿Hay alguna manera de que PDO trate esto correctamente o debería crear mi instrucción SQL con un en línea si cambiar el "=" con "es" y cambiar el tercer parámetro bindValue por el correcto?

Respuesta

6

Si está utilizando MySQL, puede usar el NULL-safe equal operator <=> no estándar, que puede comparar ya sea nulo o valores no nulos.

$stmt = $dbh->prepare('SELECT id, name FROM folders WHERE parent_folder_id <=> :id'); 
$stmt->bindValue(':id', $folder_id, PDO::PARAM_INT); 

Este operador siempre devuelve verdadero o falso, no es NULL, que es lo que se obtiene si se intenta comparar nada a NULL con iguales =.

ANSI SQL define un predicado IS [NOT] DISTINCT FROM que funciona de manera similar, pero no es compatible con todos los proveedores (aún).

+2

¡Gracias! Esto hizo el truco y tú también me enseñaste algo, nunca antes había usado <=> (sí, un poco para la fiesta, ¿eh?). Me salvará un montón de dolores de cabeza en el futuro, eso es seguro :) – Gazillion

0

Quizás esto?

<?php 
    $stmt = $dbh->prepare('SELECT id, name FROM folders WHERE parent_folder_id = :id'); 
    if (is_null($folder_id)) { 
    $stmt->bindParam(':id',null, PDO::PARAM_NULL); 
    } else { 
    $stmt->bindParam(':id', $folder_id, PDO::PARAM_INT); 
    } 

No se ha probado aunque

EDIT:

Más o menos así:

<?php 
    if (is_null($folder_id)) {  
     $stmt = $dbh->prepare('SELECT id, name FROM folders WHERE parent_folder_id IS NULL'); 
    } else { 
     $stmt = $dbh->prepare('SELECT id, name FROM folders WHERE parent_folder_id = :id'); 
     $stmt->bindParam(':id', $folder_id, PDO::PARAM_INT); 
    } 

Yo sé que no es óptimo, pero sigue siendo DOP cochecito ...

+0

Eso no soluciona el problema de que no obtengo ningún resultado porque si es NULL, entonces tendría que cambiar la forma en que preparo mi consulta sql. Sé cómo lo haría si ese fuera el caso (con un if-in en línea), pero tengo la sensación de que PDO es probablemente lo suficientemente inteligente como para cambiar esto para mí y simplemente no sé cómo. – Gazillion

+0

No confíe demasiado en PDO: el mantenedor principal se fue hace unos 2 años, y el proyecto se ha estancado bastante desde entonces. –

+0

Gracias, lo tendré en cuenta :) – Gazillion

2

Puede usar el NULL-safe equal operator, <=>. Su consulta debe ser SELECT id, name FROM folders WHERE parent_folder_id <=> :id

Si alguna vez cambia a otra base de datos y necesita actualizar la consulta, algunos de ellos tienen un NOT DISTINCT FROM que hace más o menos lo mismo.

+0

Lo siento, no vi la respuesta de Bill cuando la publiqué – shesek

+0

Gracias, era la respuesta correcta, pero eras demasiado lenta (por unos segundos jejeje)! ;) – Gazillion

Cuestiones relacionadas