Postgres «столбец $3 не существует» при использовании параметров

#node.js #postgresql

Вопрос:

Я сталкиваюсь с ошибкой при попытке использовать параметры как часть моего запроса.

Примечательными частями моей схемы являются:

name_tokens tsvector

cards.rarity card_rarity который представляет собой пользовательское перечисление, созданное из: create type card_rarity as enum ('C', 'T', 'R', 'S', 'M', 'L', 'F', 'P');

Самый неприятный вопрос заключается в следующем:

 SELECT cards.* FROM cards WHERE
(name_tokens @@ to_tsquery("$1"::text)) AND
(cards.rarity = "$2"::card_rarity)
      ORDER BY cards.id;
 

с вводом:

 [ 'absorb amp; in', 'L' ]
 

Когда я запускаю это, сообщение об ошибке гласит:

UnhandledPromiseRejectionWarning: error: column "$3" does not exist .

Когда я запускаю этот запрос без параметров, он работает нормально, т. Е.:

 SELECT cards.* FROM cards WHERE
(name_tokens @@ to_tsquery('absorb amp; in') AND
(cards.rarity = 'L')
      ORDER BY cards.id;
 

Я хотел бы иметь возможность использовать параметры, так как прямое добавление пользовательских строк в запрос может быть опасным.

Есть какие-нибудь идеи о том, почему я получаю эту ошибку? Я предполагаю, что это какое-то неправильное форматирование или использование кавычек, когда я не должен или что-то в этом роде. Любая помощь будет признательна 🙂

Изменить: Было предложено, чтобы я попробовал:

 SELECT cards.* FROM cards WHERE
(name_tokens @@ to_tsquery($1::text)) AND
(cards.rarity = $2::card_rarity)
ORDER BY cards.id;
 

Но когда я это делаю, я получаю следующую ошибку:
UnhandledPromiseRejectionWarning: error: could not determine data type of parameter $1

Ответ №1:

PostgreSQL использует двойные кавычки для идентификаторов (таких как имена таблиц и столбцов), поэтому это:

 SELECT cards.* FROM cards WHERE
(name_tokens @@ to_tsquery("$1"::text)) AND
(cards.rarity = "$2"::card_rarity)
      ORDER BY cards.id;
 

содержит два идентификатора в кавычках "$1" и "$2" заполнители без номеров, но без них.

Если вы хотите использовать нумерованные заполнители, опустите двойные кавычки:

 SELECT cards.* FROM cards WHERE
(name_tokens @@ to_tsquery($1::text)) AND
(cards.rarity = $2::card_rarity)
      ORDER BY cards.id;
 

Я не уверен, откуда это "$3" взялось, хотя я бы предположил, что ошибка исходит из другого запроса с аналогичной ошибкой цитирования.

Комментарии:

1. Когда я пытаюсь это сделать, я получаю следующую ошибку: UnhandledPromiseRejectionWarning: error: could not determine data type of parameter $1

2. Вы уверены, что ищете правильный вопрос? Приведения типов обычно решают такого рода проблемы.

3. ДА. Это строка, которую я называю запросом: await pool.query(searchQuery.getSearchQuery(), searchQuery.getInputs()); Где SearchQuery.getSearchQuery() возвращает: SELECT cards.* FROM cards WHERE (name_tokens @@ to_tsquery($1::text)) AND (cards.rarity = $2::card_rarity) и входные данные: [ 'absorb amp; in', 'L' ] Я использую пакет pg из npm для пула. запрос.

4. Ладно! Я все понял! Итак, мне .getSearchQuery() снова позвонили. И, к сожалению, это не истинное «попадание» в том смысле, что оно изменяет состояние (которое я должен исправить), что приводило к неправильной строке в 2 раза, когда она была вызвана.

5. Да, я так считаю, он добавлял дополнительные входные данные каждый раз, когда его вызывали. Теперь все исправлено! Надеюсь, Damp;D было весело!