Динамический 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
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))
вывод будет динамический запрос.