PostgreSQL - SQL 状态:42601 语法错误

Lea*_*dro 7 database postgresql bulkinsert dynamic-sql plpgsql

我想知道如何在函数内使用动态查询。我尝试了很多方法,但是,当我尝试编译我的函数时,会显示一条消息 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;
Run Code Online (Sandbox Code Playgroud)

我收到的错误消息:

ERROR:  syntax error at or near "return"
LINE 5:     WITH v_tb_person AS (return query execute sql)
Run Code Online (Sandbox Code Playgroud)

我尝试使用:

WITH v_tb_person AS (execute sql)

WITH v_tb_person AS (query execute)

WITH v_tb_person AS (return query execute)
Run Code Online (Sandbox Code Playgroud)

怎么了?我怎么解决这个问题?

这是一个与PostgreSQL 等效的 Oracle “批量收集”相关的问题

Erw*_*ter 10

你的函数将像这样工作:

CREATE OR REPLACE FUNCTION prc_tst_bulk(sql text)
  RETURNS TABLE (name text, rowcount int)
  LANGUAGE plpgsql AS 
$func$
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     
$func$;
Run Code Online (Sandbox Code Playgroud)

称呼:

SELECT * FROM prc_tst_bulk($$SELECT a AS name, b AS nome, c AS gender FROM tbl$$)
Run Code Online (Sandbox Code Playgroud)

您无法按照您尝试的方式混合普通 SQL 和动态 SQL。整个语句要么都是动态的,要么都是纯 SQL 的。因此,我正在构建一个动态声明来使这项工作发挥作用。您可能对手册中有关执行动态命令的章节感兴趣。

聚合函数count()返回bigint,但您已rowcount定义为integer,因此您需要显式强制转换::int才能使其工作。

我使用美元引用来避免引用地狱。

然而,这应该是一个用于SQL 注入攻击的蜜罐,还是你真的打算使用它?对于您非常私密和安全的使用,这可能还不错 - 尽管我什至不相信自己有这样的功能。如果不受信任的用户有任何可能的访问权限,那么这样的功能就是一把上膛的枪。要保证这个安全是不可能的。

当 Craig(SQL 注入的死敌)看到您从他对前面问题的回答中伪造的内容时,他可能会受到轻微的打击。:)

顺便说一句,这个查询本身看起来很奇怪。这两个SELECT术语可以合并为一个。但这不是重点。

  • 不,一切都很好。我向你保证,它仍然让我感到抽搐。 (2认同)