PostgreSQL - SQL状态:42601语法错误

时间:2013-04-30 04:00:32

标签: database postgresql plpgsql bulkinsert dynamic-sql

我想知道如何在函数内部使用动态查询。我已经尝试了很多方法,但是,当我尝试编译我的函数时,会显示一条消息SQL 42601。

我使用的代码:

CREATE OR REPLACE FUNCTION prc_tst_bulk(sql text)
RETURNS TABLE (name text, rowcount integer) AS 
$$
BEGIN
  WITH v_tb_person AS (return query execute sql)
  select name, count(*) from v_tb_person where nome like '%a%' group by name
  union
  select name, count(*) from v_tb_person where gender = 1 group by name;
END     
$$ LANGUAGE plpgsql;

我收到的错误讯息:

ERROR:  syntax error at or near "return"
LINE 5:     WITH v_tb_person AS (return query execute sql)

我尝试使用:

WITH v_tb_person AS (execute sql)

WITH v_tb_person AS (query execute)

WITH v_tb_person AS (return query execute)

有什么问题?我该如何解决这个问题?

这是一个与PostgreSQL equivalent of Oracle “bulk collect”

相关的问题

1 个答案:

答案 0 :(得分:3)

你的功能会像这样:

CREATE OR REPLACE FUNCTION prc_tst_bulk(sql text)
RETURNS TABLE (name text, rowcount integer) AS 
$$
BEGIN

RETURN QUERY EXECUTE '
WITH v_tb_person AS (' || sql || $x$)
SELECT name, count(*)::int FROM v_tb_person WHERE nome LIKE '%a%' GROUP BY name
UNION
SELECT name, count(*)::int FROM v_tb_person WHERE gender = 1 GROUP BY name$x$;

END     
$$ LANGUAGE plpgsql;

呼叫:

SELECT * FROM prc_tst_bulk($$SELECT a AS name, b AS nome, c AS gender FROM tbl$$)
  • 您不能以尝试的方式混合纯SQL和动态SQL。整个语句要么全部是动态的,要么都是纯SQL。所以我正在构建一个动态语句来使其工作。您可能对executing dynamic commands in the manual

  • 这一章感兴趣
  • 汇总函数count()返回bigint,但您已将rowcount定义为integer,因此您需要使用显式广告::int来制作{{1}}这项工作

  • 我使用dollar quoting来避免引用地狱。

但是,这应该是SQL injection 攻击的蜜罐还是您真的会使用它?对于你非常私密和安全的使用,它可能是好的 - 尽管我甚至不相信自己有这样的功能。如果对不受信任的用户有任何可能的访问权限,则此类功能是加载的步枪。这是不可能的 使这安全。

克雷格(SQL注入的死敌!)可能会轻轻一击,当他在your preceding question的答案中看到你从他的代码中伪造的东西。 :)

查询本身看起来很奇怪,顺便说一下。但这不是重点。