2009-09-08 97 views
90

我使用此代碼,我以後無奈:如何使用PDO插入NULL值?

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, '',所有這些失敗並引發此錯誤:

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

回答

116

我剛開始學習PDO,但我認爲你需要使用bindValue,不bindParam

bindParam需要一個變量,要引用,並在值在調用bindParam的時候不拉。我發現這在對php文檔的評論中:

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

編輯:你可能會想這樣做bindValue(':param', null, PDO::PARAM_NULL);,但它並沒有對每個人的工作(謝謝你會剃鬚刀報告。)

+0

我不確定這兩者之間的區別,但我會調查一些。謝謝,你的回答也很棒。 – Nacho 2009-09-08 03:29:44

+3

我認爲這可能是比我的更好的答案(如果確實有效) – 2010-03-04 19:51:41

+0

我在PHP 5.3.8 + Mysql上的測試顯示,兩者之間生成的查詢沒有差異。重要的部分似乎是傳遞的值爲NULL,而不是''或'0' – Odin 2011-11-06 18:19:11

42

當使用bindParam()你必須傳遞一個變量,而不是一個常數。因此,該行之前,你需要創建一個變量並將其設置爲null

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

你會得到相同的錯誤消息,如果你嘗試過:

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

你說得對,我剛剛意識到我之前在我的代碼中完成了它,$ null = PDO :: PARAM_NULL;謝謝。 – Nacho 2009-09-08 03:31:46

+1

在這種情況下,最好使用bindValue(),如果你打算使用佔位符。 bindParam()最初是爲了執行查詢,然後更改變量並重新執行而不再綁定參數。 bindValue()立即綁定,bindParam()僅在執行時綁定。 – 2015-10-07 08:49:53

+0

我發現$ myNull = null行中的null必須是小寫字母。 $ myNull = NULL不起作用。 – raphael75 2017-11-28 15:11:24

24

當使用INTEGER列(可以是NULL)在MySQL,PDO有一些(我)意外行爲。

如果您使用$stmt->execute(Array),則必須指定文字NULL,並且不能通過變量引用給出NULL。 所以這是行不通的:

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

但是這將工作:

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

試過這在MySQL 5.5.15和PHP 5.4.1

+0

$ stmt-> execute(array( ':param'=>!empty($ val)?$ val:null )); 使用!因爲對於空字符串,您還希望在數據庫中設置爲空 – 2017-06-30 19:36:42

+0

@ShehzadNizamani只有在列類型爲整數時才如此,就像在他的示例中一樣,是的。但是否則'isset()'更好地與'NULL'關聯。一個空字符串也是一個值。 – StanE 2017-11-17 02:25:29

5

對於那些誰仍然有問題(無法通過參考傳遞參數2),定義一個具有空值的變量,而不僅僅是將空值傳遞給PDO:

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

希望這有助於。

3

如果要插入NULL只有當valueempty'',但插入value可用時。

A)使用POST方法接收表單數據,並使用這些值調用函數插入。

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

B)評估是否一個字段不是由用戶填充,並插入NULL如果是這種情況。

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

例如,如果用戶確實對形式的productName領域沒有任何輸入,然後$productNameSETEMPTY。因此,您需要檢查它是否爲empty(),如果是,則插入NULL

測試在PHP 5.5.17

祝你好運,

+1

或者,您可以在查詢字符串中使用MySQL的'IFNULL()'函數。像這樣:'; $ sql =「INSERT INTO products(productId,productName),VALUES(IFNULL(:productId,NULL),IFNULL(:productName,NULL))」;' – starleaf1 2014-12-10 05:22:02

+0

我喜歡清潔你的解決方案。我只是測試它,但不幸的是,當用戶沒有在輸入上寫任何東西時,它插入空字符串而不是NULL。這只是一個偏好問題,但我寧願使用NULL而不是空字符串。 – 2014-12-14 23:10:41

6

我有同樣的問題,我發現這個解決方案與bindParam工作:

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

嘗試。

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

在嘗試回答這樣一個老問題之前,您應該先閱讀其他答案。可能它已經被回答了。 – 2017-05-04 04:44:00