我有以下(对我来说有点复杂)MariaDB 10.6更新:

update survey_definition sd
    join (select si.survey_def_id, si.status, si.end_date
          from survey_instance si
          where si.survey_def_id = ?1
            and si.status not in (14)
          order by si.end_date desc
          limit 1) latest on sd.id = latest.survey_def_id
set sd.latest_result=latest.status,
    sd.latest_survey_end_date=latest.end_date;

如何将其转化为jOOQ DSL? 有可能吗?

My best (unfinished) try is: enter image description here

JOOQ版本:3.12.1

DSL文本:

dslContext.update(SURVEY_DEFINITION
    .join(dslContext.select (SURVEY._INSTANCE.SURVEY_DEFINITION_ID, SURVEY_INSTANCE.STATUS, SURVEY_INSTANCE.END_TIME_MILLIS)
        . from(SURVEY_INSTANCE) SelectJoinStep<Record3<String, ScanStatus, Long>>
        . where(SURVEY_INSTANCE.SURVEY_DEFINITION_ID.eq(definitionId)) SelectConditionStep<Record3<Sting, ScanStatus, Long>>
        . limit(1) SelectLimitPercentStep<Record3<Sting, ScanStatus, Long>>
        .on (SURVEY_INSTANCE.ID.eq(SURVEY_DEFINITION.ID))
    )

触发的.on():"Cannot resolve method 'on' in '"SelectLimitPercentStep'".

UPD:我想出了以下解决方案:

        final Table<Record3<String, ScanStatus, Long>> latest = dslContext
            .select(SURVEY_INSTANCE.SURVEY_DEFINITION_ID, SURVEY_INSTANCE.STATUS, SURVEY_INSTANCE.END_TIME_MILLIS)
            .from(SURVEY_INSTANCE)
            .where(DSL.and(
                SURVEY_INSTANCE.SURVEY_DEFINITION_ID.eq(definitionId),
                SURVEY_INSTANCE.STATUS.notEqual(ScanStatus.DELETED))
            )
            .orderBy(SURVEY_INSTANCE.END_TIME_MILLIS.desc())
            .limit(1)
            .asTable("latest");
        dslContext.update(SURVEY_DEFINITION
                .join(latest)
                .on(latest.field(SURVEY_INSTANCE.SURVEY_DEFINITION_ID).eq(SURVEY_DEFINITION.ID)))
            .set(SURVEY_DEFINITION.LATEST_SCAN_STATUS, latest.field(SURVEY_INSTANCE.STATUS))
            .where(SURVEY_DEFINITION.ID.eq(definitionId))
            .execute();

感谢@LukasEder和@Vonc的帮助和 idea .

推荐答案

您提供的SQL查询是一个复杂的UPDATE语句,其中包含一个子查询的JOIN子句.在jOOQ中,您可以使用DSLContextupdate()个方法,结合用于JOIN子句的join()on()个方法以及用于UPDATE子句的set()个方法来构建这样的查询.

为了避免任何可读性问题(如放错位置的圆括号),您可以分解查询.

我将假设:

  • 您的survey_definitionsurvey_instance表分别生成为SURVEY_DEFINITIONSURVEY_INSTANCE.您需要导入生成的表.如果没有生成它们,则需要手动创建它们.
  • 你有你的DSLContext作为context可用.
  • 原始SQL中的?1是稍后提供的参数.在jOOQ DSL中,我将其替换为param("?1", Integer.class).

然后,代码将是:

import static org.jooq.impl.DSL.*;
import static com.example.generated.Tables.*;

// Assuming the DSLContext is available as "context"

SurveyDefinition SD = SURVEY_DEFINITION.as("sd");
SurveyInstance SI = SURVEY_INSTANCE.as("si");

Field<Integer> surveyDefId = field(name("survey_def_id"), Integer.class);
Field<Integer> status = field(name("status"), Integer.class);
Field<Timestamp> endDate = field(name("end_date"), Timestamp.class);

Table<?> latest = context
    .select(SI.SURVEY_DEF_ID.as(surveyDefId), SI.STATUS.as(status), SI.END_DATE.as(endDate))
    .from(SI)
    .where(SI.SURVEY_DEF_ID.eq(param("?1", Integer.class)), SI.STATUS.notIn(14))
    .orderBy(SI.END_DATE.desc())
    .limit(1)
    .asTable("latest");

context.update(SD)
    .join(latest)
    .on(SD.ID.eq(latest.field(surveyDefId)))
    .set(SD.LATEST_RESULT, latest.field(status))
    .set(SD.LATEST_SURVEY_END_DATE, latest.field(endDate))
    .execute();

注意:代码假设LATEST_RESULTLATEST_SURVEY_END_DATESURVEY_DEFINITION表中的列的名称完全相同,并且它们的类型与子查询中的类型匹配.如果不是这样,您可能需要更改这些名称或添加类型转换.

As you can see, I am using the on() method (part of the ON clause on a TableOnStep object, which is returned by the join(latest) call.
I am not using on() not on a SelectLimitPercentStep object (which does not have an on() method, hence your original error message "Cannot resolve method 'on' in '"SelectLimitPercentStep'").

context.update(SD)
    .join(latest)
    .on(SD.ID.eq(latest.field(surveyDefId)))
    ...

Here, latest is a Table object that represents a derived table.
So calling on() in this context should not trigger a compilation error.


由于某些原因,我不能在context.update(SD)之后进行联接,根本没有这样的方法.可能是因为jOOQ版本较旧.

An alternative workaround would be to perform the subquery first, store its results, and then use these results in the update statement.
As an example:

// First, execute the subquery and fetch the results
Record3<String, Integer, Date> record = dslContext.select(SURVEY_INSTANCE.SURVEY_DEF_ID, SURVEY_INSTANCE.STATUS, SURVEY_INSTANCE.END_DATE)
    .from(SURVEY_INSTANCE)
    .where(SURVEY_INSTANCE.SURVEY_DEF_ID.eq(definitionId))
    .and(SURVEY_INSTANCE.STATUS.notIn(14))
    .orderBy(SURVEY_INSTANCE.END_DATE.desc())
    .limit(1)
    .fetchOne();

// Next, use the results of the subquery in the UPDATE statement
if (record != null) {
    dslContext.update(SURVEY_DEFINITION)
        .set(SURVEY_DEFINITION.LATEST_RESULT, record.get(SURVEY_INSTANCE.STATUS))
        .set(SURVEY_DEFINITION.LATEST_SURVEY_END_DATE, record.get(SURVEY_INSTANCE.END_DATE))
        .where(SURVEY_DEFINITION.ID.eq(record.get(SURVEY_INSTANCE.SURVEY_DEF_ID)))
        .execute();
}

此解决方法将操作分为两个部分,它首先从子查询中获取记录,然后使用该数据执行更新.

Java相关问答推荐

试图弄清楚资源未能在我的Android应用程序中调用关闭警告

如何在Java中对自定义协议进行主机名验证?

将@ManyToOne JPA Composite Key用作Id保存实体添加额外参数

如何在Spring Security中设置CustomLogin路径?

为什么我们仍然需要实现noArgsConstructor如果Java默认提供一个非参数化的构造函数?''

使用GridBagLayout正确渲染

为什么Java编译器不区分不同类型的方法?

生成桥方法以解决具有相同擦除的冲突方法

Jenv-相同的Java版本,但带有前缀

try 从REST API返回对象列表时出错

删除打印语句会影响功能...腐败在起作用?

Spring Validator批注不起作用

记录是类的语法糖吗?

循环不起作用只有第一个元素重复

如何在Maven Central上部署?

模拟JUnit未检测到返回字符串的方法的任何声纳覆盖

如何在Spring Security中设置一个任何人都可以打开的主页?

如何修复Spring Boot应用程序中的RestDocumentationGenerationException:java.io.FileNotFoundException:/curl-request.adoc(只读文件系统)?

如何使用带有可选参数的类生成器?

HBox内部的左对齐按钮(如果重要的话,在页码内)