如何绑定一个值,如果我想让它接受INT和NULL与PDO


How to bind a value if I want it to accept both INT and NULL with PDO?

$stmt = $dbh->prepare( 'SELECT id, name FROM folders WHERE parent_folder_id = :id' );
$stmt->bindValue( ':id', $folder_id, PDO::PARAM_INT );
我有上面的代码。如果一个文件夹有一个parent_folder_id,那么它意味着它是在另一个文件夹。如果此列为NULL,则表示它是根文件夹。

从我的理解,如果$folder_id是NULL,那么它将把它视为0(所以我没有得到结果的代码,因为它是因为在该列的值是NULL而不是0)。如果我改变第三个参数PDO::PARAM_NULL我仍然没有得到结果。我相信这是因为它将查询评估为"WHERE parent_folder_id = NULL",这与"WHERE parent_folder_id为NULL"不相等。

是否有办法让PDO正确对待这一点,或者我应该用内联if创建我的SQL语句来改变"="与"Is",并将bindValue第三个参数与正确的交换?

如果您正在使用MySQL,您可以使用非标准的null安全相等操作符<=>,它可以比较null或非null值。

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

此操作符总是返回true或false,而不是NULL,如果您尝试将任何内容与NULL进行比较,则会得到NULL = =

ANSI SQL定义了一个类似的谓词IS [NOT] DISTINCT FROM,但它不是所有供应商(尚未)支持。

您可以使用null安全的相等运算符<=>。你的查询应该是SELECT id, name FROM folders WHERE parent_folder_id <=> :id

如果你曾经改变到另一个数据库,需要更新查询,其中一些有一个NOT DISTINCT FROM做同样的事情。

也许是这个?

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

未测试

编辑:

更多像这样的东西:

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

我知道这不是最佳的,但PDO仍然有bug…