Динамический SQL-запрос в Postgres

Я пытался использовать динамический SQL для запуска некоторых запросов в postgres.

Пример:

EXECUTE format('SELECT * from result_%s_table', quote_ident((select id from ids where condition = some_condition)))

Мне нужно запросить таблицу, которая имеет вид result_%s_table, где мне нужно заменить правильное имя таблицы (идентификатор) из другой таблицы.

Я получаю ошибку ERROR: prepared statement "format" does not exist

Ссылка: подстановка строки с результатом запроса postgresql

5 ответов

Решение

EXECUTE ... USING работает только в PL/PgSQL - т.е. внутри функций или DO блоки, написанные на языке PL/PgSQL. Это не работает в простом SQL; EXECUTE в простом SQL совершенно другой, для выполнения подготовленных операторов. Вы не можете использовать динамический SQL напрямую в диалекте SQL PostgreSQL.

Для сравнения:

Смотрите 2-й последний пункт в моем предыдущем ответе.


В дополнение к тому, что он не работает, за исключением PL/PgSQL, ваш SQL-оператор неверен, он не будет выполнять то, что вы ожидаете. Если (select id from ids where condition = some_condition) возвращается сказать 42, заявление потерпит неудачу, если id является целым числом Если это приведено к тексту, вы получите:

EXECUTE format('SELECT * from result_%s_table', quote_ident('42'));
EXECUTE format('SELECT * from result_%s_table', '"42"');
EXECUTE 'SELECT * from result_"42"_table';

Это неверно. Вы на самом деле хотите result_42_table или же "result_42_table", Вы должны написать что-то вроде:

EXECUTE format('SELECT * from %s', quote_ident('result_'||(select id from ids where condition = some_condition)||'_table'))

... если вы должны использовать quote_ident,

CREATE OR REPLACE FUNCTION public.exec(
text)
RETURNS SETOF RECORD
LANGUAGE 'plpgsql'
AS $BODY$
BEGIN 
    RETURN QUERY EXECUTE $1 ; 
END 
$BODY$;

использование:

select * from exec('select now()') as t(dt timestamptz)

Попробуйте использовать

RETURN QUERY EXECUTE '<SQL Command>'

Это вернет данные в виде таблицы. Вы должны использовать это в хранимой функции PostgreSQL.

Я уже создал полную демонстрацию по пользовательскому фильтру и пользовательской сортировке с использованием динамического запроса PostgreSQL. Пожалуйста, посетите этот URL: http://www.dbrnd.com/2015/05/postgresql-dynamic-sql/

Все это выглядит сложнее, чем вопрос ОП. Различное форматирование должно сработать... но это может быть абсолютно так, что я не понимаю.

Из того, как я прочитал вопрос ОП, я думаю, что другие в подобной ситуации могут извлечь выгоду из того, как я его получил.

Я использую Postgre на Redshift, и я столкнулся с этой проблемой и нашел решение.

Я пытался создать динамический запрос, указав собственную дату.

date = dt.date(2018, 10, 30)

query = ''' select * from table where date >= ''' + str(my_date) + ''' order by date '''

Но запрос полностью игнорирует условие при его наборе таким образом.

Однако, если вы используете знак процента (%), вы можете правильно вставить дату.

Один правильный способ написать приведенное выше утверждение:

query = ''' select * from table where date >= ''' + ''' '%s' ''' % my_date + ''' order by date '''

Так что, может быть, это полезно, а может и нет. Надеюсь, это поможет хотя бы одному человеку в моей ситуации!

С наилучшими пожеланиями.

EXECUTE будет работать только в среде pl/pqsql.

вместо EXECUTE попробуйте с SELECT

 SELECT format('SELECT * from result_%s_table', quote_ident((select id from ids where condition = some_condition))

вывод будет динамический запрос.

Другие вопросы по тегам