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

Ho il codice sopra. Se una cartella ha un parent_folder_id, significa che si trova all'interno di un'altra cartella. Se questa colonna è NULL, significa che è una cartella radice.Come associare un valore se voglio che accetti sia INT sia NULL con PDO?

Dalla mia comprensione se $ folder_id è NULL quindi lo tratterà come 0 (quindi non ottengo risultati con il codice così com'è perché il valore in quella colonna è NULL e non 0). Se cambio il terzo argomento in PDO :: PARAM_NULL non ottengo ancora risultati. Credo che questo sia perché valuta la query come "WHERE parent_folder_id = NULL" che non è uguale a "WHERE parent_folder_id è NULL".

C'è un modo per fare in modo che PDO lo consideri correttamente o dovrei creare la mia istruzione SQL con un inline se modificare "=" con "is" e scambiare il terzo parametro bindValue con quello corretto?

risposta

6

Se utilizzi MySQL, puoi utilizzare lo standard non standard NULL-safe equal operator <=>, che può confrontare sia null che valori non nulli.

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

Questo operatore restituisce sempre vero o falso, non è NULL, che è quello che si ottiene se si tenta di confrontare qualcosa a NULL con uguale =.

ANSI SQL definisce un predicato IS [NOT] DISTINCT FROM che funziona in modo simile, ma non è ancora supportato da tutti i fornitori.

+2

Grazie! Questo ha fatto il trucco e tu mi hai insegnato qualcosa anch'io, non avevo mai usato <=> prima (ehi, un po 'alla festa, eh?). Mi risparmierà un sacco di mal di testa in futuro, questo è sicuro :) – Gazillion

0

Forse questo?

<?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); 
    } 

Non testato se

EDIT:

più o meno così:

<?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); 
    } 

io so che non è ottimale, ma DOP è ancora buggy ...

+0

Questo non risolve il problema che non ottengo risultati perché se è NULL dovrei invece cambiare il modo in cui preparo la mia query sql. So come lo farei se fosse il caso (con un inline-if), ma ho la sensazione che PDO sia abbastanza intelligente da cambiare questo per me e io non so come. – Gazillion

+0

Non fidatevi troppo del PDO: il principale manutentore se n'è andato circa 2 anni fa, e da allora il progetto è abbastanza in stallo. –

+0

Grazie, lo terrò a mente :) – Gazillion

2

È possibile utilizzare NULL-safe equal operator, <=>. La vostra query dovrebbe essere SELECT id, name FROM folders WHERE parent_folder_id <=> :id

Se mai passa a un altro database e necessario aggiornare la query, alcuni di loro ha un NOT DISTINCT FROM che fa la stessa cosa.

+0

Scusa, non ho visto la risposta di Bill quando l'ho postata – shesek

+0

Grazie, era la risposta giusta ma eri troppo lento (di pochi secondi hehehe)! ;) – Gazillion

Problemi correlati