【问题标题】:JOOQ multiset throwing syntax exceptionJOOQ 多集抛出语法异常
【发布时间】:2022-01-17 22:08:18
【问题描述】:

最近移至 JOOQ 3.15.5 并尝试了 Multiset 功能,但它正在抛出 SQLSyntaxErrorException。以下是我写的查询:

dslContext.select(
    tableA.asterisk(),
    multiset(
            select(tableB.DELETED, tableB.VALUE)
                .from(tableB)
                .where(tableB.ORDER_ID.eq(tableA.ORDER_ID))
    ).as("bookingAdditions")
).from(tableA)
 .where(tableA.BATCH_ID.greaterThan(batchId))
 .fetchInto(BookingDto.class);

这里是关系:

|tableA|  1           n  |tableB| 
|      | --------------> |      | 
|      |                 |      | 
--------                  --------
(tableA)                  (tableB) 

这是由 JOOQ 生成的查询:

set @t = @@group_concat_max_len; set @@group_concat_max_len = 4294967295; select `tablea`.*, (select coalesce(json_merge_preserve('[]', concat('[', group_concat(json_array(`v0`, `v1`) separator ','), ']')), json_array()) from (select `tableb`.`deleted` as `v0`, `tableb`.`value` as `v1` from `db_name`.`booking_additions` as `tableb` where `tableb`.`order_id` = `tablea`.`order_id`) as `t`) as `bookingadditions` from `db_name`.`booking` as `tablea` where `tablea`.`batch_id` > 0; set @@group_concat_max_len = @t;

以下是例外情况:

org.jooq.exception.DataAccessException: SQL [set @t = @@group_concat_max_len; set @@group_concat_max_len = 4294967295; select `tablea`.*, (select coalesce(json_merge_preserve('[]', concat('[', group_concat(json_array(`v0`, `v1`) separator ','), ']')), json_array()) from (select `tableb`.`deleted` as `v0`, `tableb`.`value` as `v1` from `db_name`.`booking_additions` as `tableb` where `tableb`.`order_id` = `tablea`.`order_id`) as `t`) as `bookingadditions` from `db_name`.`booking` as `tablea` where `tablea`.`batch_id` > ?; set @@group_concat_max_len = @t;]; You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'set @@group_concat_max_len = 4294967295; select `tablea`.*, (select coalesce(jso' at line 1
    at org.jooq_3.15.5.MYSQL.debug(Unknown Source)
    at org.jooq.impl.Tools.translate(Tools.java:2988)
    at org.jooq.impl.DefaultExecuteContext.sqlException(DefaultExecuteContext.java:639)
    at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:349)
    at org.jooq.impl.AbstractResultQuery.fetchLazy(AbstractResultQuery.java:295)
    at org.jooq.impl.AbstractResultQuery.fetchLazyNonAutoClosing(AbstractResultQuery.java:316)
    at org.jooq.impl.SelectImpl.fetchLazyNonAutoClosing(SelectImpl.java:2866)
    at org.jooq.impl.ResultQueryTrait.collect(ResultQueryTrait.java:357)
    at org.jooq.impl.ResultQueryTrait.fetchInto(ResultQueryTrait.java:1423)
    at com.company.BookingDAO.fetchBookings(BookingDAO.java:118)
    at

我正在使用Mysql: 5.7。我究竟做错了什么?有什么提示吗?

【问题讨论】:

  • 您使用的是商业版的 jOOQ,因为免费版不支持 MySQL 5.7。仅支持最新版本 (8)

标签: mysql sql jooq


【解决方案1】:

关于多条语句

除了Bill Karwin 所说的,您还可以将Settings.renderGroupConcatMaxLenSessionVariable 指定为false,并为您的会话或您自己的服务器增加服务器的@@group_concat_max_len 变量。

这里 jOOQ 的默认设置是假设添加 JDBC 连接标志比更改服务器设置更容易,但这两种方法都是可行的。

关于相关派生表

这种特殊的模拟需要支持相关的派生表,而 MySQL 5.7 不支持,请参阅https://github.com/jOOQ/jOOQ/issues/12045。你不会得到一个相关的MULTISET 表达式以在 MySQL 5.7 上工作,但你可以编写一个几乎等效的 MULTISET_AGG 表达式,如下所示:

dslContext.select(
    tableA.asterisk(),
    multisetAgg(tableB.DELETED, tableB.VALUE).as("bookingAdditions")
).from(tableA)
 .join(tableB).on(tableB.ORDER_ID.eq(tableA.ORDER_ID))
 .where(tableA.BATCH_ID.greaterThan(batchId))
 // You can group by the primary key, or tableA.fields() if you don't have a PK
 .groupBy(tableA.ID)
 .fetchInto(BookingDto.class);

MULTISET 不同,MULTISET_AGG 生成NULL 值而不是空列表,以防您加入tableB,这在SQL 聚合函数中很常见。然后,您可以使用coalesce(multisetAgg(...), multiset(...)) 作为解决方法。

【讨论】:

    【解决方案2】:

    当您在查询中使用GROUP_CONCAT() 时,jOOQ 会生成三个用分号分隔的 SQL 语句。不幸的是,MySQL 的默认行为是不允许在单个请求中进行多个查询。

    您必须更改 JDBC 连接选项以包括 allowMultiQueries

    在此处了解更多信息:https://blog.jooq.org/mysqls-allowmultiqueries-flag-with-jdbc-and-jooq/

    【讨论】:

      猜你喜欢
      • 2014-06-25
      • 2018-01-29
      • 1970-01-01
      • 2021-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-24
      • 1970-01-01
      相关资源
      最近更新 更多