当前位置: 首页 > 知识库问答 >
问题:

jooq、postgres和从多表更新和返回数据失败

梁存
2023-03-14

当更新其中一个表中的字段时,我很难制定一个jooq查询来返回两个表中的数据。(Postgres 9.6,jooq 3.11)

表DEVICE和CUSTOMER在外键约束设备上联接。CUSTOMERID=CUSTOMER.ID。

我想返回一个合格的device.id和设备客户的customer.secret,并更新device.stateIN_PROGRESS。资格由各种条款评估。

我开始用

  final Record task = db
      .update(DEVICE)
      .set(DEVICE.STATE, StateEnum.IN_PROGRESS)
      .from(CUSTOMER)
         .where(DEVICE.CUSTOMERID.eq(CUSTOMER.ID))
         .and(DEVICE.STATE.eq(StateEnum.NEW))
         .and(CUSTOMER.SECRETCONFIRMED.eq(true))
      .returning(DEVICE.ID, CUSTOMER.SECRET)
      .fetchOne();    

这导致了错误:字段(“public”。“客户”。“机密”)不包含在行

我基于这个带有连接的Postgres返回子句对另一个查询进行了建模,但最终出现了相同的错误。

  final Record task = db
      .update(DEVICE)
      .set(DEVICE.STATE, StateEnum.IN_PROGRESS)
      .from(CUSTOMER, db
         .select()
         .from(CUSTOMER
            .join(DEVICE).on(CUSTOMER.ID.eq(DEVICE.CUSTOMERID)))
         .forUpdate()
      )
      .where(DEVICE.STATE.eq(StateEnum.NEW))
      .and(CUSTOMER.SECRETCONFIRMED.eq(true))
      .returning(DEVICE.ID, CUSTOMER.SECRET)
      .fetchOne();

 ERROR:  Field ("public"."customer"."secret") is not contained in Row  

我尝试了几种排列,最后出现了一些错误变体

  • 表名

我相信,有可能提出这样的质疑,但我已经没有想法了。有什么建议吗?

我尝试过的变体的代表性列表

  final Record task = db
      .update(DEVICE)
      .set(DEVICE.STATE, StateEnum.IN_PROGRESS)
      .from(
          DEVICE.join(CUSTOMER).on(DEVICE.CUSTOMERID.eq(CUSTOMER.ID)))
      .where(DEVICE.STATE.eq(StateEnum.NEW))
      .and(CUSTOMER.SECRETCONFIRMED.eq(true))
      .returning(DEVICE.ID, CUSTOMER.SECRET)
      .fetchOne();

  ERROR: table name "device" specified more than once

  final Record task = dbContext
  .update(DEVICE.join(CUSTOMER).on(DEVICE.CUSTOMERID.eq(CUSTOMER.ID)))
      .set(DEVICE.STATE, StateEnum.IN_PROGRESS)
      .where(DEVICE.STATE.eq(StateEnum.NEW))
      .and(CUSTOMER.SECRETCONFIRMED.eq(true))
      .returning(DEVICE.ID, CUSTOMER.SECRET)
      .fetchOne();

  ERROR: syntax error at or near "join"

  final Record task = db
      .update(DEVICE)
      .set(DEVICE.STATE, StateEnum.IN_PROGRESS)
      .from(db.select().from(CUSTOMER,
          DEVICE.join(CUSTOMER).on(DEVICE.CUSTOMERID.eq(CUSTOMER.ID))).forUpdate()
      )
      .where(DEVICE.STATE.eq(StateEnum.NEW))
      .and(CUSTOMER.SECRETCONFIRMED.eq(true))
      .returning(DEVICE.ID, CUSTOMER.SECRET)
      .fetchOne();

  ERROR: table name "customer" specified more than once

  final Record task = db
      .update(DEVICE)
      .set(DEVICE.STATE, StateEnum.IN_PROGRESS)
      .from(db.select().from(
          DEVICE.join(CUSTOMER).on(DEVICE.CUSTOMERID.eq(CUSTOMER.ID))).forUpdate()
      )
      .where(DEVICE.STATE.eq(StateEnum.NEW))
      .and(CUSTOMER.SECRETCONFIRMED.eq(true))
      .returning(DEVICE.ID, CUSTOMER.SECRET)
      .fetchOne();

  ERROR: missing FROM-clause entry for table "customer"


  final Record task = db
      .update(DEVICE)
      .set(DEVICE.STATE, StateEnum.IN_PROGRESS)          

    .from(CUSTOMER.join(DEVICE).on(CUSTOMER.ID.eq(DEVICE.CUSTOMERID)))
      .where(DEVICE.STATE.eq(StateEnum.NEW))
      .and(CUSTOMER.SECRETCONFIRMED.eq(true))
      .returning(DEVICE.ID, CUSTOMER.SECRET)
      .fetchOne();

  ERROR: table name "device" specified more than once

共有1个答案

孟祯
2023-03-14

这是因为jOOQ API中的一个旧设计错误,其中返回()子句导致返回类型为Result

然而,自jOOQ 3.11以来,现在可以调用returningResult()作为一种解决方法,以获得您指定的确切行类型:https://github.com/jOOQ/jOOQ/issues/7475

 类似资料:
  • 我正在使用Jooq的和方法将一些数据添加到Postgres表中。以后我想知道我的数据中有多少重复项,因此如果插入或更新了一行,就需要返回。 根据我到目前为止对postgres的具体研究,我发现是一个有效的选项。但是,从jOOQ中自动生成的Java表类似乎不能让我访问像Xmax这样的postgres的系统列。 我已经重新检查了Maven jOOQ表生成配置,并且不排除任何列。我也在Jooq自己的网站

  • 但现在我也需要知道: 插入了多少行 由于现有而更新了多少行 由于约束无法插入多少行 如果最后一行没有遵守约束,那么以前插入/更新的行是否会保留在数据库中?

  • 使用< code>node-postgres我想更新我的用户模型中的列,目前我有这个 所以我可以做到这一点 但是,如果我想更新多个列和值,我目前正在做一些非常低效的事情,并调用该方法x次(即对于每个查询) 我如何通过只调用一次数据库来生成这个。 谢谢

  • 问题内容: 我想知道以下内容: 如何从数据库中的多个表中获取数据? 有哪些类型的方法可以做到这一点? 什么是联接和工会,它们之间有何不同? 什么时候应该使用每个与其他比较? 我打算在我的应用程序(例如,PHP)中使用此功能,但是不想对数据库运行多个查询,我需要在单个查询中从多个表中获取数据的哪些选项? 注意:我正在写这篇文章是因为我希望能够链接到有关我在PHP队列中不断遇到的众多问题的书面指南,因

  • 我有一个Postgres函数,它返回一个表“RestURNS TABLE......” 代码中有一些商业规则。如果不满足某些条件,我只想返回一个空记录集。有没有简单的方法?或者我需要为返回的每个列选择一个NULL吗? 现在,若我尝试只返回NULL,它会抱怨:错误:查询的结构和函数结果类型不匹配。