Как предотвратить ПДО от интерпретации вопросительного знака в качестве заполнителя?
Для обнаружения существования ключа в hstore, мне нужно выполнить такой запрос:
SELECT * FROM tbl WHERE hst ? 'foo'
Однако, это дает мне PDOException:
PDOException: SQLSTATE[HY093]: Invalid parameter number: no parameters were bound: SELECT * FROM tbl WHERE hst ? 'foo'
Есть ли способ избежать вопросительного знака, чтобы PDO не взял его в качестве заполнителя? Я пытался использовать до четырех обратных косых черт, а также двойной вопросительный знак (??), но ничто, кажется, не убеждает PDO оставить вопросительный знак в покое.
3 ответов:
Используйте форму вызова функции. Согласно системным каталогам, оператор hstore
?использует функциюexist:regress=# select oprname, oprcode from pg_operator where oprname = '?'; oprname | oprcode ---------+--------- ? | exist (1 row)Итак, вы можете написать:
SELECT * FROM tbl WHERE exist(hst,'foo');(Лично я не большой поклонник операторно-ориентированного дизайна и документации hstore, я думаю, что он отбрасывает полезные свойства самодокументирования интерфейса на основе функций без какой-либо реальной пользы, и я обычно использую его вызовы функций, а не его операторы. Только потому, что вы можете определить операторы, не означает, что вы должен.)
У меня была та же проблема при поиске по данным JSONB. Полный Вопрос здесь
SELECT * FROM post WHERE locations ? :location;Обходной путь для
PostgreSQL 9.5аналогичен:SELECT * FROM post WHERE jsonb_exists(locations, :location);Я также открыл билет в системе отслеживания ошибок PHP
Обновление
Как уже упоминалось Diabl0, предложенное решение работает, но не использует индекс. Проверено с помощью:
CREATE INDEX tempidxgin ON post USING GIN (locations);
Я предлагаю Вам отключить PDO native prepared statement, чтобы вопросительные знаки игнорировались:
$pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, true);
Comments