2015-05-26 2 views
12

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

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

Для этого я выполняю подготовленные заявления с именованными заполнителями.

Однако я столкнулся с интересной проблемой, пытаясь использовать некоторые из новых 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?

ответ

18

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

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

Например:

CREATE OPERATOR [email protected] (LEFTARG = jsonb, RIGHTARG = text, PROCEDURE = jsonb_exists)  
CREATE OPERATOR [email protected]| (LEFTARG = jsonb, RIGHTARG = text[], PROCEDURE = jsonb_exists_any) 
CREATE OPERATOR [email protected]& (LEFTARG = jsonb, RIGHTARG = text[], PROCEDURE = jsonb_exists_all) 

Так что можно использовать [email protected], [email protected]| и [email protected]& вместо ?, ?| и ?& соответственно. например

$sth = $dbh->prepare("SELECT * FROM stuff WHERE meta [email protected] :value"); 
$sth->bindValue(1, $value, PDO::PARAM_STR); 
$sth->execute(); 
+0

Ha! На самом деле еще не подумал об этом, попробуй сейчас, большое спасибо! – Fraser

+0

Блестящее определение оператора - идеальное решение, так как это означает, что я могу использовать одну и ту же структуру без необходимости иметь дело с любыми вызовами функций. Действительно оценил это, почесывал голову в течение нескольких часов, думая об этом с конца PDO, а не с конца db. Опять же, большое спасибо. – Fraser

+0

Примечание.В документации нет таких функций, как jsonb_exists, jsonb_exists_any, jsonb_exists_all, но они действительно работают как jsonb_exists (jsonb, text) – Swayok

Смежные вопросы