SELECT 来自更新的结果 ... 在 jOOQ 中返回

SELECT from result of UPDATE ... RETURNING in jOOQ

我正在将一些旧的 PostgreSQL 代码转换为 jOOQ,我目前正在努力处理具有多个 WITH 子句的 SQL,其中每个子句都依赖于前一个。最好保持 SQL 逻辑的编写方式而不是更改它(例如,对 DB 的多个查询)。

看起来,SELECT 无法对正在更新...返回的内容进行操作,例如

dsl.select(DSL.asterisk())
   .from(dsl.update(...)
            .returning(DSL.asterisk())
   )

我创建了一些测试 tables,试图创建某种 MVCE:

create table dashboard.test (id int primary key not null, data text); --test table

with updated_test AS (
    UPDATE dashboard.test SET data = 'new data'
    WHERE id = 1
    returning data
),
    test_user AS (
        select du.* from dashboard.dashboard_user du, updated_test -- from previous WITH
        where du.is_active AND du.data = updated_test.data
    )
SELECT jsonb_build_object('test_user', to_jsonb(tu.*), 'updated_test', to_jsonb(ut.*))
FROM test_user tu, updated_test ut; -- from both WITH clauses

到目前为止,这是我的 jOOQ 代码(用 Kotlin 编写):

dsl.with("updated_test").`as`(
                dsl.update(Tables.TEST)
                        .set(Tables.TEST.DATA, DSL.value("new data"))
                        .returning(Tables.TEST.DATA) //ERROR is here: Required Select<*>, found UpdateResultStep<TestRecord>
        ).with("test_user").`as`(
                dsl
                        .select(DSL.asterisk())
                        .from(
                                Tables.DASHBOARD_USER,
                                DSL.table(DSL.name("updated_test")) //or what to use here?
                        )
                        .where(Tables.DASHBOARD_USER.IS_ACTIVE.isTrue
                                .and(Tables.DASHBOARD_USER.DATA.eq(DSL.field(DSL.name("updated_test.data"), String::class.java)))
                        )

        )
                .select() //here goes my own logic for jsonBBuildObject (which is tested and works for other queries)
                .from(
                        DSL.table(DSL.name("updated_test")), //what to use here
                        DSL.table(DSL.name("test_user")) //or here
                )

是否有任何解决方法?如果可能,我想避免更改 SQL。 此外,在这个项目中,这个技巧经常用于从 UPDATE 子句中获取 JSON(B)(table 也有 JSON(B) 列):

with _updated AS (update dashboard.test SET data = 'something' WHERE id = 1 returning *)
select to_jsonb(_updated.*) from _updated;

如果没有解决方法,这对我们来说将是真正的倒退。

我正在使用 JOOQ 版本 3.13.3 和 Postgres 12.0.

jOOQ 目前不支持此功能,请参阅:

解决方法一如既往,当某些特定于供应商的语法不受支持时,求助于plain SQL templating

例如

// If you don't need to map data types
dsl.fetch("with t as ({0}) {1}", update, select);

// If you need to map data types
dsl.resultQuery("with t as ({0}) {1}", update, select).coerce(select.getSelect()).fetch();