...或问号问题。
我目前正在使用新的jsonb类型在php中实现postgres数据库的搜索功能。
为实现这一目标,我正在使用命名占位符执行预准备语句。
然而,在尝试使用一些新的postgres JSON containment and existence operators以及命名占位符时,我遇到了一个有趣的问题。
问题的基础是运营商自己使用问号?
作为其语法的一部分。即。
?
密钥/元素字符串是否存在于JSON值中?
?|
是否存在任何这些键/元素字符串?
?&
是否存在所有这些键/元素字符串?
这意味着我在PHP中的语句如下所示。
$sth = $dbh->prepare("SELECT * FROM stuff WHERE meta ? :value");
$sth->bindValue(1, $value, PDO::PARAM_STR);
$sth->execute();
此操作失败,因为问号被解释为占位符。 为了解决这个问题,我试图让运算符本身成为一个命名参数。
$sth = $dbh->prepare("SELECT * FROM stuff WHERE meta :operator :value");
$sth->bindValue(1, $operator, PDO::PARAM_STR);
$sth->bindValue(2, $value, PDO::PARAM_STR);
$sth->execute();
然而,这只会引起与使用裸操作符相同的错误,即
ERROR: syntax error at or near \"$1\"1
是否有其他人遇到此问题,或者有人能想到一个好的解决方法吗?
有没有办法逃避或传递问号,以便可以使用postgres jsonb包含和存在运算符与PDO参数化查询?
答案 0 :(得分:19)
您可以使用相应的函数而不是运算符(jsonb_exists,jsonb_exists_any,jsonb_exists_all)。例如在psql中运行\do+ "?"
以查看函数名称?操作
或者在没有“?”的情况下定义自己的运算符而不是符号。
例如:
CREATE OPERATOR ~@ (LEFTARG = jsonb, RIGHTARG = text, PROCEDURE = jsonb_exists)
CREATE OPERATOR ~@| (LEFTARG = jsonb, RIGHTARG = text[], PROCEDURE = jsonb_exists_any)
CREATE OPERATOR ~@& (LEFTARG = jsonb, RIGHTARG = text[], PROCEDURE = jsonb_exists_all)
因此,可以分别使用~@
,~@|
和~@&
代替?
,?|
和?&
。 e.g。
$sth = $dbh->prepare("SELECT * FROM stuff WHERE meta ~@ :value");
$sth->bindValue(1, $value, PDO::PARAM_STR);
$sth->execute();