#php #postgresql #pdo
В SQL-запросе используется символ знака вопроса - ? и PDO пытается биндить к нему значение ($1), но в данной ситуации это совершенного не нужно, т.к. символ знака вопроса это оператор языка SQL для работы с типом данных JSONB. Как обойти этот механизм присвоения значений? $statement = "SELECT id FROM public.parameter WHERE variations ?| array[ 'something' ] LIMIT 1 OFFSET 0;"; $sth = $this->pdo->prepare( $statement ); $sth->execute();
Ответы
Ответ 1
Вместо таких операторов можно использовать соответствующие функции (jsonb_exists, jsonb_exists_any, jsonb_exists_all). К примеру, если запустить в psql команду \do+ "?", выведется имя функции, которая вызывается оператором ?. А можно определить собственный оператор без символов ?, например: 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(); Это перевод вот этого ответа с английского StackOverflow от пользователя alexius.Ответ 2
Для решения этой ситуации на http://stackoverflow.com предлагают создать свои собственные операторы без символа ? и выглядит это вот так: -- Because PHP::PDO replace symbol '?' into SQL-query we can not use this operator for work with JSONB type. -- alternative operator for '?' CREATE OPERATOR ~@ (LEFTARG = jsonb, RIGHTARG = text, PROCEDURE = jsonb_exists); -- alternative operator for '?|' CREATE OPERATOR ~@| (LEFTARG = jsonb, RIGHTARG = text[], PROCEDURE = jsonb_exists_any); -- alternative operator for '?&' CREATE OPERATOR ~@& (LEFTARG = jsonb, RIGHTARG = text[], PROCEDURE = jsonb_exists_all); Теперь мною приведенный выше PHP-код стал рабочим (разумеется я заменил оператор ?| на ~@| $statement = "SELECT id FROM public.parameter WHERE variations ~@| array[ '" . mb_strtolower( $title ) . "' ] LIMIT 1 OFFSET 0;"; $sth = $this->pdo->prepare( $statement ); $sth->execute(); Но, друзья, это ведь костыль!
Комментариев нет:
Отправить комментарий