JOOQ 多集抛出语法异常
JOOQ multiset throwing syntax exception
最近转移到 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
。我究竟做错了什么?有什么提示吗?
当您在查询中使用 GROUP_CONCAT()
时,jOOQ 生成三个用分号分隔的 SQL 语句。不幸的是,MySQL 的默认行为是不允许在单个请求中进行多个查询。
您必须更改 JDBC 连接选项以包括 allowMultiQueries
。
在此处阅读更多相关信息:https://blog.jooq.org/mysqls-allowmultiqueries-flag-with-jdbc-and-jooq/
关于多重陈述
除了所说的之外,您还可以将Settings.renderGroupConcatMaxLenSessionVariable
指定为false
并为您的会话或您自己的服务器增加服务器的@@group_concat_max_len
变量.
jOOQ 在这里的默认设置是假设添加 JDBC 连接标志比更改服务器设置更容易,但这两种方法都是可行的。
关于相关派生表
此特定仿真需要支持相关派生表,MySQL 5.7 不支持,请参阅 https://github.com/jOOQ/jOOQ/issues/12045. You're not going to get a correlated MULTISET
expression to work on MySQL 5.7, but you could write an almost equivalent 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(...))
作为解决方法。
最近转移到 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
。我究竟做错了什么?有什么提示吗?
GROUP_CONCAT()
时,jOOQ 生成三个用分号分隔的 SQL 语句。不幸的是,MySQL 的默认行为是不允许在单个请求中进行多个查询。
您必须更改 JDBC 连接选项以包括 allowMultiQueries
。
在此处阅读更多相关信息:https://blog.jooq.org/mysqls-allowmultiqueries-flag-with-jdbc-and-jooq/
关于多重陈述
除了Settings.renderGroupConcatMaxLenSessionVariable
指定为false
并为您的会话或您自己的服务器增加服务器的@@group_concat_max_len
变量.
jOOQ 在这里的默认设置是假设添加 JDBC 连接标志比更改服务器设置更容易,但这两种方法都是可行的。
关于相关派生表
此特定仿真需要支持相关派生表,MySQL 5.7 不支持,请参阅 https://github.com/jOOQ/jOOQ/issues/12045. You're not going to get a correlated MULTISET
expression to work on MySQL 5.7, but you could write an almost equivalent 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(...))
作为解决方法。