Подтвердить что ты не робот

Как запретить PDO интерпретировать знак вопроса в качестве заполнителя?

Для обнаружения существования ключа в hstore мне нужно запустить такой запрос:

SELECT * FROM tbl WHERE hst ? 'foo'

Однако это дает мне исключение PDO:

PDOException: SQLSTATE[HY093]: Invalid parameter number: no parameters were bound: SELECT * FROM tbl WHERE hst ? 'foo'

Есть ли способ избежать вопросительного знака, чтобы PDO не забирал его в качестве заполнителя? Я пробовал до четырех обратных косых черт, а также двойной вопросительный знак (??), но ничто, кажется, не убеждает PDO оставить знак вопроса в покое.

4b9b3361

Ответ 1

Используйте форму вызова функции. В соответствии с системными каталогами оператор hstore ? использует функцию exist:

regress=# select oprname, oprcode from pg_operator where oprname = '?';
 oprname | oprcode 
---------+---------
 ?       | exist
(1 row)

чтобы вы могли написать:

SELECT * FROM tbl WHERE exist(hst,'foo');

(Лично я не большой поклонник проектирования и документации, ориентированной на hstore, я думаю, что он отбрасывает полезные самодокументирующие свойства функционально-ориентированного интерфейса без какой-либо реальной выгоды, и я обычно использую его вызовы функций, а не его операторы. Только потому, что вы можете определить операторы, это не значит, что вы должны.)

Ответ 2

У меня была такая же проблема при поиске по данным JSONB. Полный вопрос здесь

SELECT * FROM post WHERE locations ? :location;

Обходной путь на PostgreSQL 9.5 аналогичен:

SELECT * FROM post WHERE jsonb_exists(locations, :location);

Я также открыл билет в системе отслеживания ошибок PHP

Update

Как упоминалось в Diabl0, предлагаемое решение работает, но не использует индекс. Протестировано с помощью:

CREATE INDEX tempidxgin ON post USING GIN (locations);

Ответ 3

Я предлагаю вам отключить собственный подготовленный оператор PDO, поэтому вопросительные знаки будут игнорироваться:

$pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, true);