【问题标题】:Updating rows in jOOQ with joins使用连接更新 jOOQ 中的行
【发布时间】:2019-06-05 10:36:08
【问题描述】:

我认为 jOOQ 中的更新不支持联接,因此我一直在探索如何解决它...

我的第一次尝试是使用where in,但问题是MySQL不支持FROM子句中的目标表:

create
    .update(USER)
    .set(USER.name, concat(USER.NAME, "some text"))
    .where(USER.ID.in(
        create
            .select(USER.ID)
            .from(USER)
            .join(TEAM)
            .on(USER.TEAM_ID.eq(TEAM.ID))
            .where(TEAM.STATE.equal("test"))
    ))
    .execute();

我的第二次尝试是为 USER 使用临时表(灵感来自 this 答案)。问题是,我不知道如何在选择中引用临时表。到目前为止,这是我使用本机 SQL 的尝试:

create
    .update(USER)
    .set(USER.name, concat(USER.NAME, "some text"))
    .where(USER.ID.in(
        create
            .select("user_nested.id") // This line doesn't work
            .from("SELECT * FROM user AS user_nested")
            .join(TEAM)
            .on("user_nested.team_id = team.id")
            .where(TEAM.STATE.equal("test"))
    ))
    .execute();

我最终想要得到的查询是这样的:

UPDATE user
SET user.name = concat(user.email, 'some text')
WHERE user.id IN (
    SELECT user_nested.id
    FROM (SELECT * FROM user) AS user_nested
    JOIN team
    ON user_nested.team_id = team.id
    WHERE team.state = 'test'
);

这可以用jOOQ实现吗?如果没有,也许我应该对整个查询使用本机 SQL 代码。

编辑:我已经设法让它工作了,但它很笨拙,所以我仍然对替代方法感兴趣。

Janky 工作解决方案:

Field<Long> userId = DSL.field("user_nested.id", Long.class);
create
    .update(USER)
    .set(USER.NAME, (concat(USER.NAME, "some text")))
    .where(USER.ID.in(
        create
            .select(userId)
            .from("(SELECT * FROM user) AS user_nested")
            .join(TEAM)
            .on("user_nested.team_id = team.id")
            .where(TEAM.STATE.equal("test"))
    ))

【问题讨论】:

    标签: java mysql sql jooq


    【解决方案1】:

    我认为 jOOQ 中的更新不支持联接

    您可能在想,因为没有 UpdateJoinStep 类型,就像没有 SelectJoinStep 一样,所以在 jOOQ 中无法使用更新连接。但请注意,SelectJoinStep 只是为了方便。 JOIN 运算符是连接两个表的运算符,而不是 SQL 中的关键字。因此,jOOQ 支持它作为Table 类型的运算符。以您的 SQL 更新为例:

    Field<Long> userId = DSL.field("user_nested.id", Long.class);
    create
        .update(USER.join(TEAM).on(TEAM.ID.eq(USER.TEAM_ID)))
        .set(USER.NAME, (concat(USER.NAME, "some text")))
        .where(TEAM.STATE.equal("test"))
    

    您可以将上面的表格表达式传递给DSLContext.update(Table),就像其他任何表达式一样。我怀疑这已经过时了你剩下的问题?

    【讨论】:

      猜你喜欢
      • 2019-01-06
      • 2018-04-22
      • 2017-07-19
      • 2020-02-27
      • 2021-12-31
      • 2015-03-07
      • 1970-01-01
      • 2020-02-05
      • 1970-01-01
      相关资源
      最近更新 更多