jOOQ 如何解除多列的嵌套

问题描述 投票:0回答:1

参见。

unnest ( anyarray, anyarray [, ... ] )
psql 文档

那里给出的例子:

select * from unnest(ARRAY[1,2], ARRAY['foo','bar','baz']) as x(a,b) →

 a |  b
---+-----
 1 | foo
 2 | bar
   | baz

我现在想使用此功能进行批量更新。

即类似的东西

WITH
   updates as (
       SELECT * FROM unnest(
           target_ids,
           updated_foos
) as x(target_id, new_foo)
   )
UPDATE target t
    SET foo = u.new_foo
    FROM updates u
    WHERE t.id = u.target_id
;

哪里

  • target_ids
    保存要更新的实体的 id
  • updated_foos
    保存更新后的属性值
  • id 为
  • foo
     的实体的
    属性
    target_ids[i]
    应设置为
    updated_foos[i]

psql 非常简单:https://dbfiddle.uk/NRQ_ISM-

但是似乎没有相应的 jOOQ

unnest
重载可以让我这样做。 :(

我确实找到了这个 6 年前的线程 用于解除多个数组嵌套的 Jooq 表示法,我想我也可以这样做:

val targetId = "target_id"
val newFoo = "new_foo"

val updates = DSL // a table (targetId, newFoo) containing all updates to be done
    .name("updates")
    .fields(targetId, newFoo)
    .`as`(
        DSL.select(
            DSL.field(targetId),
            DSL.field(newFoo)
        ).from(
            DSL.table(
                "(SELECT * FROM unnest(?,?)) as x($targetId, $newFoo)",
                DSL.value(updatingTargets.toTypedArray()),
                DSL.value(newFoos.toTypedArray()),
            )
        )
    )

ctx
    .with(updates)
    .update(TARGET)
    .set(TARGET.FOO, updates.field(newFoo, String::class.javaObjectType))
    .from(updates)
    .where(TARGET.ID.eq(updates.field(targetId, Int::class.javaObjectType)))
    .execute()

(其中

ctx: DSLContext

但我希望有一个稍微不那么冗长的解决方案,减少对普通 sql 字符串的依赖。

postgresql jooq postgresql-13
1个回答
0
投票

“Enhanced

UNNEST
”(标准中的可选 SQL 功能 S301)的这种特殊用法非常深奥,但有时也很有趣。 jOOQ 的未来版本可能会支持它(jOOQ 3.19 中尚未支持):

但是你几乎不会真正需要它,因为你可以只使用标准 SQL

VALUES
构造函数,假设你的数组始终源自客户端代码。

values(row(1, "A"), row(2, "B"))

注意,jOOQ 有一个

org.jooq.Rows
实用程序,可以将
Stream
收集到
List<Row2<T1, T2>>
Array<Row2<T1, T2>>
,例如,但在 Kotlin 中,您可能不需要该实用程序。

© www.soinside.com 2019 - 2024. All rights reserved.