抱歉,如果有一些简单的解决方案,我没有看到,但它已经结束了,我的大脑很累。 ;)
我执行了很多查询,其中传递给我的 (PDO) 查询函数的变量可能包含一个值,或者为 null
。
但由于您不能 =
为 null
,所以当我查找 col_a = 'something' AND col_b = 'something_else'
时,我遇到了问题> 我的查询工作正常,但当第二个值为 null
时,相同的查询会失败:col_a = 'something' AND col_b = null
。它应该是 col_a = 'something' AND col_b IS null
。
将 =
动态替换为 IS
的好方法是什么?
到目前为止,我想出的唯一解决方案是搜索 =
并在我注意到我向查询添加 null
值时手动将其交换(这将在我的 ReplaceParameters()
函数中是可能的,我用它来模拟未准备查询的 PDO 参数替换功能)。
然而,这感觉又脏又低效。我非常感谢您的建议。
最佳答案
我解决了我的问题。正如我在问题中提到的,我有一个 ReplaceParameters()
我用它来对未准备好的查询执行 PDO 样式的参数替换。
在该函数中,我已经遇到了调用 $this->m_connection->quote($value, PDO::PARAM_NULL)
的问题。将参数替换为 ''
而不是null
(所以你得到 my_column = ''
而不是 my_column = null
)。
为了解决这个问题,我添加了正则表达式
$newQuery = preg_replace("/{$tempKey}\b/", "null", $newQuery);
经过一点修改,我最终得到了这个:
$newQuery = preg_replace(["/\s+=\s+{$tempKey}\b/", "/\s+(!=|<>)\s+{$tempKey}\b/"], [" IS null", " IS NOT null"], $newQuery);
第一个捕获/替换模式组合搜索 = :temp_key
并将其替换为 IS null
。第二个捕获/替换模式搜索 != :temp_key
和<> :temp_key
,并将其替换为 IS NOT null
.
编辑:在上面的解决方案中我没有考虑到一件额外的事情。更换=
!=
<>
与 IS null
和IS NOT null
应该仅发生在 WHERE
内。条款。实际设置值时,语法仍然是 SET my_column = null
.
我通过在正则表达式中添加负向后查找来解决这个问题,以仅替换 WHERE|where
右侧的参数。 :
$newQuery = preg_replace(["/(?<=WHERE|where)(.*)\s*(?<!!)=\s+{$tempKey}/", "/(?<=WHERE|where)(.*)\s*(!=|<>)\s+{$tempKey}\b/"], ["$1 IS null", "$1 IS NOT null"], $newQuery);
剩下的就是 WHERE|where
中没有的参数。堵塞。我无法为此想出一个好的正则表达式(它也一直匹配不需要的部分),所以我采用了一个更简单的解决方案:找到 WHERE
的索引/位置子句(如果存在),并提取该子句剩下的任何内容作为子字符串,并将占位符替换为 null
.
$whereIndex = stripos($newQuery, "WHERE");
if ($whereIndex !== false)
{
$newQuery = substr_replace($newQuery, preg_replace("/{$tempKey}\b/", "null", substr($newQuery, 0, $whereIndex)), 0, $whereIndex);
}
else
{
$newQuery = preg_replace("/{$tempKey}\b/", "null", $newQuery);
}
如果有人对最后一部分有基于正则表达式的解决方案的好主意,请告诉我。 如果有人想让我解释我的正则表达式或其他东西,请再次告诉我。
关于php - MySQL:在查询中动态交换 "= :value"为 "IS :value",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33899204/