具有参数化查询的jsonb存在运算符

时间:2015-05-26 14:33:47

标签: php json postgresql pdo jsonb

...或问号问题。

我目前正在使用新的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参数化查询?

1 个答案:

答案 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();