postgres中的动态sql查询
Posted
技术标签:
【中文标题】postgres中的动态sql查询【英文标题】:dynamic sql query in postgres 【发布时间】:2012-09-28 14:50:10 【问题描述】:我试图使用动态 SQL 在 postgres 中运行一些查询。
例子:
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
【问题讨论】:
【参考方案1】:这些看起来都比 OP 的问题复杂。不同的格式应该可以解决问题..但绝对可能是我不明白的情况。
从我阅读 OP 问题的方式来看,我认为处于类似情况的其他人可能会从我的方法中受益。
我在 Redshift 上使用 Postgre,我遇到了这个问题并找到了解决方案。
我试图创建一个动态查询,输入我自己的日期。
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 '''
所以,也许这有帮助,也可能没有。我希望它至少对我的情况有帮助!
最好的祝愿。
【讨论】:
【参考方案2】: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)
【讨论】:
这很简单,非常适合日常使用...展示如何将动态查询用作普通查询! 太棒了!安全只读运行动态 SQL。 . select * from run_select('update a set i = 5;') as t(account_id int);错误:无法将 UPDATE 查询作为游标打开;【参考方案3】:尝试使用
RETURN QUERY EXECUTE '<SQL Command>'
这会将数据返回为表格形式。您必须将其用于 PostgreSQL 的存储功能。
我已经创建了关于使用 PostgreSQL 的动态查询的自定义过滤器和自定义排序的完整演示。 请访问此网址: http://www.dbrnd.com/2015/05/postgresql-dynamic-sql/
【讨论】:
【参考方案4】:EXECUTE ... USING
仅适用于PL/PgSQL - 即在函数中或用PL/PgSQL 语言编写的DO
blocks 中。它不适用于纯 SQL;普通 SQL 中的 EXECUTE
完全不同,用于执行准备好的语句。不能在 PostgreSQL 的 SQL 方言中直接使用动态 SQL。
比较:
PL/PgSQL'sEXECUTE ... USING
;到
SQL's EXECUTE
查看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
。
【讨论】:
作为补充,DO
块总是返回 void 并且不接受任何参数,所以我认为 OP 仅限于一个函数。
@Clodoaldo 好点子——他们可以执行SELECT
,但除非他们做一些真正迂回的事情,比如SELECT ... INTO
一个临时表。
@CraigRinger 你好,我知道我参加聚会有点晚了,但你能推荐任何关于 postgreSQL 中动态 sql 的好教程吗?我找不到任何东西。我想创建一个多合一的动态查询。如果需要,请检查 this 问题。谢谢
"您不能在 PostgreSQL 的 SQL 方言中直接使用动态 SQL。"好吧,事实上你可以,至少使用 query_to_xml。见***.com/a/38684225/3935325
postgres 是否有任何扩展以编程方式生成动态 sql 给定参数?【参考方案5】:
EXECUTE
仅适用于 pl/pqsql 环境。
用 SELECT 代替 EXECUTE 尝试
SELECT format('SELECT * from result_%s_table', quote_ident((select id from ids where condition = some_condition))
输出将是动态查询。
【讨论】:
动态查询的文本,当然,但它不会执行查询。请参阅之前的链接帖子。 是的,我已经完成了你详细的动态 qry 执行,这里我提到的是 EXECUTE 只能在 pl/pqsql 环境中工作,当我发布我的答案时,我真的没有注意到你的回应. 不用担心。它只是没有回答问题,即如何执行动态SQL。 那么上面的语句应该在 pl/pqsql 块中,我在第一行本身就提到了。 我考虑过投反对票,因为如前所述,这不会执行该块。但是,获取查询结果并将其作为另一个查询调用再次提供并不难,动态内容是可信的。所以这解决了问题,理论上避免了注入。以上是关于postgres中的动态sql查询的主要内容,如果未能解决你的问题,请参考以下文章