【问题标题】:Postgresql - ERROR: syntax error at or near "RETURN" SQL state: 42601Postgresql - 错误:“RETURN”SQL 状态或附近的语法错误:42601
【发布时间】:2021-02-28 07:09:40
【问题描述】:

我正在使用 Postgresql 9.6 并尝试创建以下函数:

CREATE FUNCTION public."getInventory"("vals1Arg" character varying[], "vals2Arg" character varying[])
    RETURNS json
    LANGUAGE 'sql'
    
    
AS $BODY$

CREATE TEMP TABLE t1 AS 
          SELECT * FROM unnest(vals1Arg) AS u(c);

CREATE TEMP TABLE t2 AS 
          SELECT * FROM unnest(vals2Arg) AS u(c);

RETURN QUERY 
    SELECT * FROM "INVENTORY"
        JOIN t1 ON "COLUMN_1" = t1.c
        JOIN t2 ON "COLUMN_2" = t2.c;

$BODY$;

我的实际需求在单独的帖子中提到here

我收到以下语法错误:

ERROR:  syntax error at or near "RETURN"
LINE 12: RETURN QUERY 
         ^
SQL state: 42601

我该如何解决?

提前致谢!

【问题讨论】:

  • 与您的问题无关,但是:您应该真正避免使用那些可怕的带引号的标识符。他们的麻烦比他们值得的要多得多。 wiki.postgresql.org/wiki/…

标签: sql postgresql postgresql-9.6


【解决方案1】:

您不能在 language sql 函数中使用 return query

由于您使参数区分大小写,因此在使用它们时还必须引用它们。

但是当您从"INVENTORY" 表中返回所有行时,您还需要将您的函数声明为returns setof "INVENTORY"`

CREATE FUNCTION public."getInventory"("vals1Arg" character varying[], "vals2Arg" character varying[])
    RETURNS setof "INVENTORY"
    LANGUAGE sql
AS 
$BODY$
  CREATE TEMP TABLE t1 AS 
          SELECT * FROM unnest("vals1Arg") AS u(c);

  CREATE TEMP TABLE t2 AS 
          SELECT * FROM unnest("vals2Arg") AS u(c);

  SELECT i.*
  FROM "INVENTORY" i
    JOIN t1 ON i."COLUMN_1" = t1.c
    JOIN t2 ON i."COLUMN_2" = t2.c;
$BODY$;

但是临时表是不必要的(并且会减慢查询速度)。可以直接在查询中使用unnest

CREATE FUNCTION public."getInventory"("vals1Arg" character varying[], "vals2Arg" character varying[])
    RETURNS setof "INVENTORY"
    LANGUAGE sql
AS 
$BODY$
  SELECT i.*
  FROM "INVENTORY" i
    JOIN unnest("vals1Arg") AS t1(c) ON i."COLUMN_1" = t1.c
    JOIN unnest("vals2Arg") AS t2(c) ON i."COLUMN_2" = t2.c;
$BODY$;

但是你真的要加入参数吗?也许您打算使用“IN”条件?

CREATE FUNCTION public."getInventory"("vals1Arg" character varying[], "vals2Arg" character varying[])
    RETURNS setof "INVENTORY"
    LANGUAGE sql
AS 
$BODY$
  SELECT i.*
  FROM "INVENTORY" i
  WHERE i."COLUMN_1" = any("vals1Arg")
    AND i."COLUMN_1" = any("vals2Arg");
$BODY$;

【讨论】:

  • 我的输入参数会很大,长度超过 3000,我相信 IN 子句会降低查询性能。不是吗?这就是我尝试使用参数值创建临时表并改用 JOIN 的原因
  • @code-geek 我希望创建临时表(并插入行)比加入未嵌套结果要慢。但是你需要用你的数据和表格来测试它。
  • 我得到 'org.postgresql.util.PSQLException: ERROR: cannot pass more than 100 arguments to a function'。我正在从我的 Spring Boot 应用程序调用 postgres 函数
  • 你的函数只有两个参数。听起来好像您的 Java 代码没有传递两个数组,而是一个值列表 - 但这是一个完全不同的问题。
  • 糟糕!我的 Java 代码传递了一个包含 3000 多个值的列表对象。我应该传递一个数组而不是 List 对象吗?
猜你喜欢
  • 2013-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-11
  • 2012-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多