PHP/MySQL/PDO绑定空参数无效

7
我在以下代码中绑定空参数时遇到了问题。
$nullVariable = NULL;
$sql = new PDO('mysql:host=' . $Server, $User, $Password);
$sql->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$statement = $sql->prepare("SELECT * FROM Table WHERE Binary16Column = :uuid");
$statement->bindParam(":uuid", $nullVariable, PDO::PARAM_NULL);
$statement->execute();
$results = $statement->fetchAll(PDO::FETCH_ASSOC);

结果变量将是一个空数组。如果我不使用参数并修改查询为“WHERE Binary16Column IS NULL”,它会返回预期的行数。所以问题必须与我处理参数的方式有关,而不是我的SQL查询。
我的代码比上面列出的更复杂,我需要能够使用可能为空的参数变量,因此检查变量是否为空并运行不同的查询不是理想的方法。从技术上讲,我有自己的设置参数函数,在这里我正在检查变量内容是否为空,并适当地绑定参数,因此我不必编写不必要的查询数量。如果变量包含有效数据且参数类型为PARAM_LOB,则查询也可以正常工作。
有人知道我做错了什么吗?非常感谢!

请查看https://dev59.com/CnM_5IYBdhLWcg3wZSXX。 - Michael
@Michael,我也尝试过使用bindValue但没有成功。不幸的是,我认为下面xdazz和dasfisch是正确的。 - Matt
因此,在我的设置参数的函数中,我使用preg_replace(“ / = \ s +” . $ parameter。/”,“ IS NULL”,$ statement-> queryString)来重写查询,如果变量的内容为null,那么我就不必每次检查某些东西是否等于null时都要写两倍的查询数。 - Matt
3个回答

8

阅读有关三值逻辑的内容。NULL不是一个值,它是缺少值的标记,因此NULL永远不可能等于任何东西,包括自身。

然而,还有一个称为“飞船运算符”的空值安全比较运算符,它将两个空值视为等价的。

WHERE Binary16Column <=> :uuid

...应该做您所期望的事情。


谢谢!这正是我在寻找的,比起我之前用正则表达式重写查询语句并检查参数变量是否为空的方法,这种方法更好、更安全。至于它是否无法等于自身,在PHP(以及我认为JavaScript)中是可以的。$var = null; if($var === null) 将会生效。 - Matt
一些编程语言可能会以不同的方式处理 null/undef 值,但在 MySQL 和关系型数据库中,NULL 被视为所述并需要特殊处理。 - Michael - sqlbot

5

如果您想选择 Binary16Column 为空的记录,您需要使用 IS NULL 作为条件而不是 = NULL

SELECT * FROM Table WHERE Binary16Column IS NULL

你需要做的是:

$uuid = /**some value**/;

$sql = new PDO('mysql:host=' . $Server, $User, $Password);
$sql->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

if ($uuid === null) {
  $statement = $sql->prepare("SELECT * FROM Table WHERE Binary16Column IS NULL");
} else {
  $statement = $sql->prepare("SELECT * FROM Table WHERE Binary16Column = :uuid");
  $statement->bindParam(":uuid", $uuid);
}

$statement->execute();
$results = $statement->fetchAll(PDO::FETCH_ASSOC);

我原本希望PDO会重构我的查询,以便在传递PARAM_NULL时实现这种方式。只是好奇,那么PARAM_NULL的意义是什么?仅用于插入/更新吗? - Matt
2
@mattburnett PDO不会为您重写查询,您需要自己制作where条件。对于PARAM_NULL,它并不总是必要的。如果您使用php的null,PDO将为您插入db的NULL - xdazz

2
我认为你没有得到结果的原因是NULL是一个关键字。由于MySQL处理NULL值的方式,当你搜索NULL值时,我认为你需要使用IS NULL。我在我的本地数据库中进行了一些测试,其中包含NULL值。只有在使用IS NULL或IS NOT NULL时才有效。
很抱歉我无法提供更多帮助(或者如果我告诉你已经知道的内容),但似乎你需要编写单独的查询或者可能需要一些简单的逻辑来连接适当的WHERE条件,这取决于变量是否为空。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接