我在从返回用户定义复合类型集的 postgres 函数中进行选择时遇到问题。我在这里创建了一个 MRE 项目:https://github.com/sify21/testjooq
我的架构
create table person (
id bigint primary key generated by default as identity,
name varchar(50) not null,
age int not null,
unique(name)
);
create type dressing as (
id bigint,
name varchar(50),
age int,
costume varchar(50)
);
CREATE OR REPLACE FUNCTION merge_person(arr dressing[]) RETURNS SETOF dressing LANGUAGE plpgsql AS
$$
DECLARE x dressing;
BEGIN
FOREACH x IN ARRAY arr LOOP
return query insert into person(name, age) values (x.name, x.age) on conflict (name) do update set age=x.age returning id,name,age,x.costume;
END LOOP;
RETURN;
END;
$$;
首先,我无法使用
create.selectFrom(Routines.mergePerson(records))
,它报告这个错误
org.jooq.exception.DataAccessException: SQL [select "merge_person"."merge_person" from "public"."merge_person"(cast(? as "public"."dressing"[]))]; ERROR: column merge_person.merge_person does not exist
我不知道
select "merge_person"."merge_person"
来自哪里,显然merge_person
返回dressing
记录。我检查了生成的代码,com.test.db.tables.records.MergePersonRecord
在setMergePerson(Object value)
方法上有一个警告,说是Unknown data type
,但我不知道如何修复它。
其次,如果我使用
create.select(DSL.asterisk()).from(Routines.mergePerson(records))
,记录会保存在postgres中,但返回的结果只包含id
字段,这是输出
+------------+
|merge_person|
+------------+
|1 |
|2 |
+------------+
但这不是我想要的,我想让它返回
DressingRecord
而不是
这是一个已知的限制,请参阅:
解决方法是使用辅助表类型而不是用户定义的类型:
CREATE TABLE dressing_t AS (
id bigint,
name varchar(50),
age int,
costume varchar(50)
);
CREATE OR REPLACE FUNCTION merge_person(arr dressing[])
RETURNS SETOF dressing_t
LANGUAGE plpgsql AS
$$
DECLARE x dressing;
BEGIN
FOREACH x IN ARRAY arr LOOP
RETURN QUERY
INSERT INTO person (name, age)
VALUES (x.name, x.age)
ON CONFLICT (name) DO UPDATE SET age = x.age
RETURNING id, name, age, x.costume;
END LOOP;
RETURN;
END;
$$;