Синтаксическая ошибка PostgreSQL в параметризованном запросе на "дату $1"

Пытаясь параметризовать мои SQL-запросы (используя функцию libpq PQexecParams), я застрял в синтаксической ошибке:

SELECT date $1

Ошибка:

ERROR:  syntax error at or near "$1"

2 ответа

Решение

Подготовленные заявления

Объяснение этому можно найти в главе Константы других типов руководства:

::, CAST() и синтаксисы вызова функций также могут использоваться для указания преобразований типов во время выполнения произвольных выражений, как обсуждалось в разделе 4.2.9. Чтобы избежать синтаксической неоднозначности, type 'string' синтаксис может использоваться только для указания типа простой литеральной константы. Еще одно ограничение по типу 'string' syntax является то, что он не работает для типов массивов; использование :: или же CAST() указать тип константы массива.

Жирный акцент мой.

Параметры для подготовленных операторов на самом деле не строковые литералы, а типизированные значения, поэтому вы не можете использовать форму type 'string', Используйте одну из двух других форм, чтобы привести значение к другому типу, как вы уже нашли.

Пример:

PREPARE foo AS SELECT $1::date;

EXECUTE foo('2005-1-1');

Аналогично для PQexecParams в библиотеке libpq C

Документация:

... В тексте команды SQL прикрепите явное приведение к символу параметра, чтобы показать, какой тип данных вы будете отправлять. Например:

SELECT * FROM mytable WHERE x = $1::bigint;

Это заставляет параметр $1 рассматриваться как bigint тогда как по умолчанию ему будет присвоен тот же тип, что и x. Настоятельно рекомендуется принудительно принять решение о типе параметра, либо таким образом, либо указав OID числового типа....

Альтернатива, как упомянуто в приведенной выше цитате, состоит в том, чтобы передавать OID соответствующих типов данных с paramTypes[] - если вам действительно нужен актерский состав. В большинстве случаев все должно работать нормально, чтобы Postgres мог получать типы данных из контекста запроса.

paramTypes[]

Определяет по OID типы данных, которые должны быть назначены символам параметра. Если paramTypes является NULL или любой конкретный элемент в массиве равен нулю, сервер выводит тип данных для символа параметра так же, как и для нетипизированной литеральной строки.

Вы можете получить OID типов данных из системного каталога pg_type:

SELECT oid FROM pg_type WHERE typname = 'date';

Вы должны использовать правильное имя внутреннего типа. Например: int4 за integer,
Или с удобством, приведенным к regtype:

SELECT 'date'::regtype::oid;

Это более гибко, так как также принимаются известные псевдонимы для имени типа. Например: int4, int или же integer за integer,

Решение состоит в том, чтобы использовать приведение типа вместо date:

SELECT $1::date
Другие вопросы по тегам