如何使用PDO插入NULL值?

时间:2009-09-08 03:14:13

标签: php mysql pdo null sql-insert

我正在使用此代码而且我感到非常沮丧:

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, '',所有这些都失败并抛出此错误:

  

致命错误:无法通过/ opt /...中的参考传递参数2。

9 个答案:

答案 0 :(得分:128)

我刚学习PDO,但我认为你需要使用bindValue,而不是bindParam

bindParam接受变量,引用,并且在调用bindParam时不会引入值。我在php docs的评论中发现了这个:

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

编辑:P.S。您可能会想要这样做bindValue(':param', null, PDO::PARAM_NULL);但它并不适用于所有人(感谢Will Shaver报告。)

答案 1 :(得分:46)

使用bindParam()时,您必须传入变量,而不是常量。因此,在该行之前,您需要创建一个变量并将其设置为null

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

如果您尝试过,则会收到相同的错误消息:

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

答案 2 :(得分:26)

在MySQL中使用INTEGER列(可能是NULL)时,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

使用PHP 5.4.1在MySQL 5.5.15上试过这个

答案 3 :(得分:6)

我遇到了同样的问题,我发现这个解决方案使用bindParam:

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

答案 4 :(得分:5)

对于仍有问题的人(无法通过引用传递参数2),定义一个具有null值的变量,而不只是将null传递给PDO:

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

希望这有帮助。

答案 5 :(得分:3)

如果您只想在NULLvalueempty时插入'',请在value可用时插入insert( $_POST['productId'], // Will be set to NULL if empty $_POST['productName'] ); // Will be to NULL if empty

A)使用POST方法接收表单数据,并使用这些值调用函数insert。

NULL

B)评估用户是否填写了某个字段,如果是这种情况,则插入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

例如,如果用户未在表单的$productName字段中输入任何内容,则SET将为EMPTY,但empty()。因此,您需要检查它是NULL,如果是,请插入{{1}}。

在PHP 5.5.17上测试

祝你好运,

答案 6 :(得分:0)

试试这个。

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

答案 7 :(得分:0)

我正在使用:

  • SQLite,

  • 带有占位符的准备好的语句,用于处理未知数量的字段,

  • 用户发送的
  • AJAX请求,其中一切是字符串,并且没有NULL值和

  • 之类的东西
  • 我迫切需要插入NULL,因为这不会违反外键约束(可接受的值)。

假设,现在用户发送带有值$_POST[field1]的帖子value1,该值可以是空字符串"""null""NULL"

首先,我发表声明:

$stmt = $this->dbh->prepare("INSERT INTO $table ({$sColumns}) VALUES ({$sValues})");

其中{$sColumns}就像field1, field2, ...,而{$sValues}是我的占位符?, ?, ...

然后,我收集与数组$_POST中的列名相关的$values数据替换为NULL s:

  for($i = 0; $i < \count($values); $i++)
     if((\strtolower($values[$i]) == 'null') || ($values[$i] == ''))
        $values[$i] = null;

现在,我可以执行:

$stmt->execute($values);

以及其他绕过外键约束。

如果另一方面,空字符串确实更有意义,那么您必须检查该字段是否为外键的一部分(更复杂)。

答案 8 :(得分:0)

基于其他答案,但更清楚地说明了如何实际使用此解决方案。

例如,如果您有一个空字符串作为时间值,但您想将其保存为null:

  if($endtime == ""){
    $db->bind(":endtime",$endtime=NULL,PDO::PARAM_STR);
  }else{
    $db->bind("endtime",$endtime);
  }

请注意,对于时间值,您将使用PARAM_STR,因为时间存储为字符串。