【问题标题】:jooq, postgres and update and returning data from multible tables failsjooq、postgres 以及从多个表中更新和返回数据失败
【发布时间】:2019-01-25 22:05:04
【问题描述】:

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

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

我想返回一个符合条件的 device.id 和设备客户的 customer.secret,并将 device.state 更新为 IN_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();    

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

我基于此 Postgres RETURNING clause with join 为另一个查询建模,但最终出现相同的错误。

  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  

我尝试了几种排列,结果出现了一些错误变化

  • 多次指定表名"<customer/device>"
  • 缺少表 "<customer/device>" 的 FROM 子句条目

我确信可以进行这样的查询,但我已经没有想法了。有什么建议吗?

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

  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

【问题讨论】:

    标签: postgresql sql-update jooq sql-returning


    【解决方案1】:

    这是因为 jOOQ API 中的旧设计错误,其中returning() clause 导致返回类型为Result<R>R,而不是您获取的实际列。因此,您只能从正在更新的表中返回列,而不能从任何其他表或任意表达式中返回。由于向后兼容,这不能轻易更改。

    但是,从 jOOQ 3.11 开始,您现在可以调用 returningResult() 作为一种解决方法来获取您指定的确切行类型:https://github.com/jOOQ/jOOQ/issues/7475

    【讨论】:

    • 谢谢,就像一个魅力。我可以建议对 update..returning 功能的其他非常好的手册页进行更新,以指出这种差异吗?
    猜你喜欢
    • 2020-01-21
    • 1970-01-01
    • 1970-01-01
    • 2021-02-09
    • 2019-01-06
    • 1970-01-01
    • 2018-03-27
    • 2016-12-08
    • 2021-06-06
    相关资源
    最近更新 更多