2009-09-08 118 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