Как запретить 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 оставить знак вопроса в покое.
Ответы
Ответ 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);