【问题标题】:Postgresql : ERROR: in creating temp table with list object valuesPostgresql:错误:在使用列表对象值创建临时表时
【发布时间】:2021-02-24 06:57:50
【问题描述】:

我正在编写一个 Postgresql 函数(使用 pgAdmin GUI),该函数将从我的 Spring Boot 应用程序中调用,并使用 java 列表对象作为参数

here 提到了我的实际需求,并建议使用列表值创建一个临时表以优化查询,以下是我通过引用 here 尝试过的 Postgres 函数:

CREATE FUNCTION public."getInventory"("vals1Arg" character varying[], "vals2Arg" character varying[])
    RETURNS "INVENTORY"
    LANGUAGE 'sql'      
    
AS 
$BODY$
 
// I assume the below two lines create two temp tables and populate the table 
   with my list object values
CREATE TEMP TABLE t1 AS 
          SELECT * FROM VALUES(vals1Arg)

CREATE TEMP TABLE t2 AS 
          SELECT * FROM VALUES(vals2Arg)

SELECT * FROM "INVENTORY"
    where "COLUMN_1" in (select * from t1)
    and "COLUMN_2" in (Select * from t2);  
   
 $BODY$;

以下是我如何调用 postgres 函数的代码 sn-p

@Query(nativeQuery = true, value = "select \"getInventory\" (:vals1Arg,:vals2Arg)")
    List<Inventory> getInventoryInfo(List<String> vals1Arg, List<String> vals2Arg);

由于列表会很大,我正在使用列表对象参数中的值创建一个临时表,并在我的选择查询中使用它

提前谢谢你!!

【问题讨论】:

  • 你的问题正文没有提到标题中的错误;你什么时候得到这个,这是你看到的准确、完整的措辞吗?临时表在哪里适合,未显示在您的查询中 - 它只是您更广泛的问题的一个细节,您应该忽略直到您正确完成这部分?
  • 当我在返回类型下拉列表中选择我的表名数组并尝试将函数保存在 pgAdmin 中时,我得到了错误
  • OK,所以点击edit,删除所有与该错误无关的信息(例如临时表的讨论、Java 代码),然后添加您为获取错误。分解问题并一次只关注一个部分不仅是获得帮助的最佳方式,也是编程中最重要的技能之一。
  • 显示函数定义和调用SQL语句。请不要作为图像,而是作为格式化文本。
  • @LaurenzAlbe,我已经编辑了这个问题。请看一下并指导我哪里出错了

标签: postgresql spring-data-jpa postgresql-9.4 pgadmin-4


【解决方案1】:

有几个问题:

  1. CREATE TABLE ... AS 的语法应该是

    CREATE TABLE ... AS
       SELECT * FROM (VALUES (...)) AS alias;
    

    而不是

    CREATE TABLE ... AS
       SELECT * FROM VALUES (...);
    

    您需要这些括号和别名。

  2. 查询中的子选择不起作用,因为它将varchar (COLUMN_1) 与varchar[](临时表的列)进行比较。

    要做到这一点,你必须

    SELECT * FROM "INVENTORY"
       WHERE "COLUMN_1" = ANY (SELECT * FROM t1);
    

如果你想创建临时表而不是直接在SELECT中使用数组,你最好

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

ANALYZE t1, t2;

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

这假定列表不包含重复条目。

【讨论】:

  • 我收到语法错误“错误:在“返回”或附近出现语法错误。关于如何解决它的任何想法?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-22
  • 2021-09-08
  • 2020-10-31
  • 2012-04-23
相关资源
最近更新 更多