2009-09-08 9 views
90

Sto usando questo codice e sono al di là di frustrazione:Come inserire valori NULL usando PDO?

try { 
    $dbh = new PDO('mysql:dbname=' . DB . ';host=' . HOST, USER, PASS); 
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    $dbh->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES 'utf8'"); 
} 
catch(PDOException $e) 
{ 
    ... 
} 
$stmt = $dbh->prepare('INSERT INTO table(v1, v2, ...) VALUES(:v1, :v2, ...)'); 
$stmt->bindParam(':v1', PDO::PARAM_NULL); // --> Here's the problem 

PDO::PARAM_NULL, null, '', tutti loro fallire e gettare questo errore:

Fatal error: Cannot pass parameter 2 by reference in /opt/...

risposta

116

Sto scoprendo DOP, ma penso che è necessario utilizzare bindValue, non bindParam

bindParam prende una variabile, fare riferimento, e non tirare in un valore al momento di chiamare bindParam. Ho trovato questo in un commento sui documenti PHP:

bindValue(':param', null, PDO::PARAM_INT); 

EDIT: P.S. Si può essere tentati di fare questo bindValue(':param', null, PDO::PARAM_NULL);, ma non ha funzionato per tutti (grazie Will rasoio per la segnalazione.)

+0

Non sono sicuro della differenza tra questi due, ma ne esaminerò alcuni. Grazie, anche la tua risposta è stata fantastica. – Nacho

+3

Penso che questa potrebbe essere una risposta migliore della mia (se funziona davvero) –

+0

i miei test su PHP 5.3.8 + Mysql mostrano che non c'è differenza nella query generata tra i due. La parte importante sembra essere che il valore passato sia NULL e non '' o '0' – Odin

42

Quando si utilizza bindParam() si deve passare in una variabile, non una costante. Quindi, prima che la linea è necessario creare una variabile e impostarla null

$myNull = null; 
$stmt->bindParam(':v1', $myNull, PDO::PARAM_NULL); 

Si potrebbe ottenere lo stesso messaggio di errore se si è tentato:

$stmt->bindParam(':v1', 5, PDO::PARAM_NULL); 
+0

Hai ragione, mi sono appena reso conto che lo avevo già fatto nel mio codice, $ null = PDO: PARAM_NULL; Grazie. – Nacho

+1

In questo caso è meglio utilizzare bindValue(), se si desidera creare segnaposto. bindParam() è originariamente concepito per eseguire una query, quindi modificare le variabili e rieseguirle senza vincolare nuovamente i parametri. bindValue() si collega immediatamente, bindParam() solo all'esecuzione. –

+0

Ho trovato che null deve essere in minuscolo nella riga $ myNull = null. $ myNull = NULL NON ha funzionato. – raphael75

24

Quando si utilizza INTEGER colonne (che può essere NULL) in MySQL, DOP ha qualche (per me) un comportamento imprevisto .

Se si utilizza $stmt->execute(Array), è necessario specificare il valore letterale NULL e non è possibile fornire NULL per riferimento variabile. Quindi questo non funziona:

// $val is sometimes null, but sometimes an integer 
$stmt->execute(array(
    ':param' => $val 
)); 
// will cause the error 'incorrect integer value' when $val == null 

Ma questo funzionerà:

// $val again is sometimes null, but sometimes an integer 
$stmt->execute(array(
    ':param' => isset($val) ? $val : null 
)); 
// no errors, inserts NULL when $val == null, inserts the integer otherwise 

provato questo su MySQL 5.5.15 con PHP 5.4.1

+0

$ stmt-> execute (array ( ': param' => empty ($ val) $ val: null )!?); Usa! Vuoto perché per la stringa vuota si vorrebbe anche impostare null nel database –

+0

@ShehzadNizamani Solo se il tipo di colonna è intero, come nel suo esempio, sì. Ma altrimenti 'isset()' si correla meglio a 'NULL'. Anche una stringa vuota è un valore. – StanE

5

Per coloro che hanno ancora problemi (non può passare parametro 2 per riferimento), definire una variabile con valore nullo, non solo passare null a DOP:

bindValue(':param', $n = null, PDO::PARAM_INT); 

Spero che questo aiuti.

3

Se si desidera inserire NULL solo quando la value è empty o '', ma inserire il value quando è disponibile.

A) Riceve i dati del modulo utilizzando il metodo POST e chiama la funzione insert con tali valori.

insert($_POST['productId'], // Will be set to NULL if empty  
     $_POST['productName']); // Will be to NULL if empty         

B) valuta se un campo non è stato riempito dall'utente, e inserisce NULL se questo è il caso.

public function insert($productId, $productName) 
{ 
    $sql = "INSERT INTO products ( productId, productName) 
       VALUES (:productId, :productName)"; 

    //IMPORTANT: Repace $db with your PDO instance 
    $query = $db->prepare($sql); 

    //Works with INT, FLOAT, ETC. 
    $query->bindValue(':productId', !empty($productId) ? $productId : NULL, PDO::PARAM_INT); 

    //Works with strings. 
    $query->bindValue(':productName',!empty($productName) ? $productName : NULL, PDO::PARAM_STR); 

    $query->execute();  
} 

Ad esempio, se l'utente non fornisce nulla sul productName campo del modulo, quindi $productName sarà SET ma EMPTY. Quindi, è necessario verificare se è empty(), e se lo è, quindi inserire NULL.

Testato su PHP 5.5.17

Buona fortuna,

+1

Oppure, è possibile utilizzare la funzione 'IFNULL()' di MySQL nella stringa di query. Come questo: '$ sql = "INSERT INTO prodotti (ProductId, productName), i valori (IFNULL (: ProductId, NULL), IFNULL (: ProductName, NULL))";' – starleaf1

+0

Mi piace la pulizia la vostra soluzione. L'ho appena testato, ma sfortunatamente inserisce stringhe vuote invece di NULL quando l'utente non scrive nulla sull'input. È solo una questione di preferenza, ma preferisco avere NULL invece di stringhe vuote. –

6

Ho avuto lo stesso problema e ho trovato questa soluzione lavora con BindParam:

bindParam(':param', $myvar = NULL, PDO::PARAM_INT); 
-1

Try This.

$stmt->bindValue(':v1', null, PDO::PARAM_NULL); // --> insert null 
+0

Prima di provare a rispondere a una domanda così vecchia, dovresti prima leggere altre risposte. Potrebbe essere già stato risposto. –

Problemi correlati