экзистенциальные операторы jsonb с параметризованными запросами


...или вопросительный знак.

В настоящее время я внедряю функцию поиска для базы данных postgres на php, которая использует новый тип jsonb.

Для достижения этой цели я выполняю подготовленные инструкции с именованными заполнителями.

Однако я столкнулся с интересной проблемой, пытаясь использовать некоторые из новых операторов хранения и существования postgres JSON вместе с именованными заполнителями.

В основе проблемы лежит то, что сами операторы используют знак вопроса ? как часть своего синтаксиса. т.е.

? Существует ли строка ключа/элемента в значении 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?

Author: Fraser, 2015-05-26

1 answers

Вы можете использовать соответствующие функции вместо операторов (jsonb_exists, jsonb_exists_any, jsonb_exists_all). например, запустите \do+ "?" в psql, чтобы увидеть имя функции? оператор.

Или определите свой собственный оператор без символа "?" вместо этого.

Например:

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)  

Чтобы можно было использовать ~@, ~@| и ~@& вместо ?, ?| и ?& соответственно. например,

$sth = $dbh->prepare("SELECT * FROM stuff WHERE meta ~@ :value");
$sth->bindValue(1, $value, PDO::PARAM_STR);
$sth->execute();
 19
Author: alexius, 2015-05-30 07:19:58