问题描述
我正在编写一个Postgresql函数(使用pgAdmin GUI),它将使用Java列表对象作为参数从Spring Boot应用程序中调用
提到了我的实际需求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$;
@Query(nativeQuery = true,value = "select \"getInventory\" (:vals1Arg,:vals2Arg)")
List<Inventory> getInventoryInfo(List<String> vals1Arg,List<String> vals2Arg);
由于列表将很大,因此我将使用列表对象参数的值创建一个临时表,并将其用于我的选择查询中
提前谢谢!
解决方法
有几个问题:
-
CREATE TABLE ... AS
的语法应为CREATE TABLE ... AS SELECT * FROM (VALUES (...)) AS alias;
代替
CREATE TABLE ... AS SELECT * FROM VALUES (...);
您需要这些括号和别名。
-
查询中的子选择不起作用,因为它会将
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;
这假定列表中没有重复的条目。