如何使用Jooq insertInto复制和修改表行

who*_*oll 8 java sql rows duplicates jooq

我正在使用Jooq并尝试在同一个表中生成数据集的近似副本.在此过程中,我想将一个字段的值更新为已知值.我一直在看文档和尝试变化,但没有运气.这是我更新REGISTRATION表并将'stage'字段设置为值6(它为5)的方法.所以我最终会得到原始数据加上一个只有不同阶段值的重复集.在伪代码中

insert into Registration (select * from Registration where stage=5) set stage=6 
Run Code Online (Sandbox Code Playgroud)

我尝试下面的代码,并认为我可以添加一个".set(...)"方法来设置值,但似乎没有效果.

create.insertInto(REGISTRATION)
    .select(
        (selectFrom(REGISTRATION)
            .where(REGISTRATION.STAGE.eq(5))
        )
    ).execute();
Run Code Online (Sandbox Code Playgroud)

Luk*_*der 5

我不知道支持INSERT .. SELECT .. SET语法的数据库,如果有这样的语法,它肯定不符合 SQL 标准。这里的前进方向是写:

在 SQL 中:

INSERT INTO registration (col1, col2, col3, stage, col4, col5)
SELECT col1, col2, col3, 6, col4, col5
FROM registration
WHERE stage = 5;
Run Code Online (Sandbox Code Playgroud)

在 jOOQ 中:

create.insertInto(REGISTRATION)
      .columns(
         REGISTRATION.COL1,
         REGISTRATION.COL2,
         REGISTRATION.COL3,
         REGISTRATION.STAGE,
         REGISTRATION.COL4,
         REGISTRATION.COL5)
      .select(
         select(
           REGISTRATION.COL1,
           REGISTRATION.COL2,
           REGISTRATION.COL3,
           val(6),
           REGISTRATION.COL4,
           REGISTRATION.COL5)
        .from(REGISTRATION)
        .where(REGISTRATION.STAGE.eq(5)))
      .execute();
Run Code Online (Sandbox Code Playgroud)

隐含以下静态导入:

import static org.jooq.impl.DSL.*;
Run Code Online (Sandbox Code Playgroud)

在 jOOQ 中,动态

由于您正在寻找动态 SQL 解决方案,因此可以这样做:

static <T> int copy(
    DSLContext create, Table<?> table, Field<T> field, 
    T oldValue, T newValue
) {
    List<Field<?>> into = new ArrayList<>();
    List<Field<?>> from = new ArrayList<>();

    into.addAll(Stream.of(table.fields())
                      .filter(f -> !field.equals(f))
                      .collect(toList()));
    from.addAll(into);

    into.add(field);
    from.add(val(newValue));

    return
    create.insertInto(table)
          .columns(into)
          .select(
             select(from)
            .from(table)
            .where(field.eq(oldValue))
          .execute();
}
Run Code Online (Sandbox Code Playgroud)