使用联接更新jOOQ中的行

时间:2019-01-10 14:20:09

标签: java mysql sql jooq

我相信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的启发)。问题是,我不知道如何在select中引用临时表。到目前为止,这是我尝试使用本机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代码。

编辑:我已经设法解决了这个问题,但是它很简陋,所以我仍然对替代方法感兴趣。

简单的解决方案:

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"))
    ))

1 个答案:

答案 0 :(得分:0)

  

我相信jOOQ中的更新不支持联接

您可能会认为,因为没有UpdateJoinStep类型,就像Typed final (tagless-final) style那样,在jOOQ中无法使用带有更新的联接。但是请注意,SelectJoinStep仅仅是为了方便。 JOIN运算符是连接两个表的运算符,不是SQL中的关键字。因此,jOOQ将其作为Table类型的运算符来支持它:

Table<?> joined = A.join(B).on(P);

您可以像上面一样将上面的表表达式传递给DSLContext.update(Table)。我怀疑这使您剩下的问题过时了吗?