使用jOOQ和连接更新行

6

我相信在jOOQ中不支持使用JOIN进行更新,因此我一直在探索如何解决这个问题...

我的第一个尝试是使用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使用临时表(启发自这个答案)。问题是,我无法找出如何在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个回答

10
我认为在jOOQ中不支持使用连接更新的操作。可能是因为没有像SelectJoinStep这样的UpdateJoinStep类型,所以您认为在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)。我猜这个操作使你的剩余问题变得过时了?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接