php - 在 PDO 中的执行函数中将 NULL 值绑定到具有关联数组的命名占位符的问题
问题描述
当table_name和conditional_clauses作为 OOP 方式的参数传递时,我正在尝试构造和执行删除查询。我通过将 PDO 包装在自定义包装器中来使用它。我正在使用带有命名占位符的准备好的语句。在每种情况下,我都会在PDO->execute()
函数内部传递一个关联数组,其中 array_keys 是使用的占位符的名称,而 array_value 是要替换的相应值。当我想用WHERE子句指定IS NULL
条件时,我只在一种情况下遇到问题。
基本上,如果我想搜索类似的内容:
SELECT * FROM EMPLOYEES WHERE salary > 10000 AND skill IS NULL
我能够动态构建一个准备好的语句,如下所示:
$sql = SELECT * FROM employees WHERE salary > :salary AND skill IS :skill
然后将准备好的 SQL 执行为:
$stmt->execute(["salary" => 10000,
"skill" => null])
这就是我面临的问题。仅当值为null时,我才在这里遇到致命错误。而且,我想在我的包装器中包含检查 IS NULL 功能。
请注意 -
我想在不使用bindValue()或 bindParam()函数的情况下达到目的。
我已经关闭了仿真(因为 MySQL 可以
正确地对所有占位符进行排序)。使用? 因为占位符不是我的选择。否则我将不得不
重新设计我的整个代码库。
这是供参考的代码片段:
<?php
class DeleteQuery {
protected function where(array $whereCondition, array &$values): string{
$whereClause = ' WHERE ';
$i = 0;
$j = 0;
$hasComparators = array_key_exists("comparators", $whereCondition);
$hasConjunctions = array_key_exists("conjunctions", $whereCondition);
$comparatorCount = $hasComparators ? count($whereCondition["comparators"]) : 0;
$conjunctionCount = $hasConjunctions ? count($whereCondition["conjunctions"]) : 0;
foreach ($whereCondition["predicates"] as $predicate_key => &$predicate_value) {
$whereClause .= $predicate_key;
$whereClause .= ($hasComparators and ($i < $comparatorCount)) ?
' ' . $whereCondition["comparators"][$i++] . ' ' : ' = ';
if (is_array($predicate_value)) {
$whereClause .= "('" . implode("', '", $predicate_value) . "')";
unset($whereCondition['predicates'][$predicate_key]);
} else {
$whereClause .= ':' . $predicate_key;
}
$whereClause .= !($hasConjunctions and ($j < $conjunctionCount)) ?
'' : ' ' . $whereCondition["conjunctions"][$j++] . ' ';
}
$values = array_merge($values, $whereCondition['predicates']);
return $whereClause;
}
public function delete($tblName, $conditions) {
$sql = "DELETE FROM " . $tblName;
$values = [];
if (!empty($conditions) && is_array($conditions)) {
/* If the stmt has WHERE clause */
if (array_key_exists("where", $conditions)) {
$sql .= $this->where($conditions['where'], $values);
}
/* If the stmt has ORDER BY clause */
if (array_key_exists("order_by", $conditions)) {
$sql .= $this->order_by($conditions['order_by']);
}
/* If the stmt has LIMIT clause */
if (array_key_exists("limit", $conditions)) {
$sql .= $this->limit($conditions['limit'], $values);
}
}
echo $sql . PHP_EOL;
print_r($values);
}
}
$deleteConditions = [
"where" => array(
"predicates" => ["skill" => null],
"comparators" => ["IS"],
),
/* other conditional clauses */
];
$obj = new DeleteQuery();
$obj->delete("employees", $deleteConditions);
解决方案
IS
运算符不能与表达式一起使用。IS NULL
并且IS NOT NULL
是关键字。
您需要一个适用于 null 和非 null 值的测试:skill
。您可以使用空安全相等运算符,<=>
$sql = 'SELECT *
FROM employees
WHERE salary > :salary
AND skill <=> :skill';
推荐阅读
- flutter - Flutter Navigator.push -> 第二页不使用新值刷新状态
- sql - 返回多于 1 行的子查询:SQL Server
- c# - 如何在 C# Web 表单应用程序的回发时保持侧导航栏隐藏?
- python - sqlalchemy.exc.InvalidRequestError:触发映射器:'映射类用户->用户'。最初的例外是:“flaskblog.Post”类未映射
- botframework - MSbot 的 MS Teams 语言选择
- python - 如何在 Pandas 中获取数据框中的确切行号?
- mysql - 谁能帮我解决这个 SQL 查询中的错误?
- python-3.x - Python 循环:列出超出范围的索引。无法访问元素
- php - 错误:Laravel 6 提供的流引用无效
- swift - 在 NSImage 上绘制透明图像