2012-10-08 155 views
13

我正在尝试使用动态SQL在postgres中运行一些查询。postgres中的动态sql查询

实施例:

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

我必须查询表,它是表格result_%s_table的方法,其中,我需要从另一个表替换为正确的表名(一个id)。

我得到的错误ERROR: prepared statement "format" does not exist

链接:string substitution with query result postgresql

回答

21

EXECUTE ... USING只能在PL/PgSQL - 即写在PL/pgSQL的语言功能或DO blocks内。它在纯SQL中不起作用;普通SQL中的EXECUTE完全不同,用于执行预准备语句。您不能直接在PostgreSQL的SQL方言中使用动态SQL。

比较:

见第2最后面值my prior answer


除不除在运行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

+1

只是补充,一个'DO'块总是返回void,并且不接受任何参数,所以我觉得OP被限制的功能。 –

+1

@Clodoaldo好点 - 他们可以执行'SELECT',但除非他们像SELECT ... INTO'这样的临时表执行一些真正的迂回操作,否则它们不会做任何好事。 –

+1

@CraigRinger你好,我知道我晚了一点晚,但你可以建议在PostgreSQL的动态SQL的任何好的教程?我找不到任何。我想创建一个全功能的动态查询。检查[this](https://stackoverflow.com/questions/48216935/pl-pgsql-for-all-in-one-dynamic-query)问题,如果你想。谢谢 – slevin

1

EXECUTE只能在pl/pqsql环境下工作。

,而不是执行与SELECT

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

输出尝试将动态查询。

+0

动态查询的文本当然可以,但它不会执行查询。查看之前的链接帖子。 –

+0

是的,我已经通过了详细的动态qry执行,这里只是我提到的是EXECUTE将只在pl/pqsql环境中工作,并且当我发布我的答案时,我真的没有注意到你的回应。 – solaimuruganv

+0

不用担心。它只是不回答这个问题,即如何执行动态SQL。 –

3

使用

RETURN QUERY EXECUTE '<SQL Command>' 

这将数据返回到表的形式尝试。你必须使用它来存储PostgreSQL的函数。

我已经创建了使用PostgreSQL动态查询的自定义过滤器和自定义排序的完整演示。 请访问此网址: http://www.dbrnd.com/2015/05/postgresql-dynamic-sql/

0
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)