Jooq 与 SQL Server 如何选择前 N 个结果

Posted

技术标签:

【中文标题】Jooq 与 SQL Server 如何选择前 N 个结果【英文标题】:Jooq with SQL Server How to select top N results 【发布时间】:2019-10-26 00:51:59 【问题描述】:

在我们的项目中,我们使用了两个数据库,一个是 postgres,一个是 mssql。我们使用 Jooq 来查询这些数据库,而使用 postgres 一切都非常简单!

但是使用 mssql 我们面临一些麻烦。任务是选择前 10 个值,假设我们有以下 java 代码:

DSL.using(conn)
.select(USE_CASE.asterisk())                                                                                                                  
.from(USE_CASE)
.where(USE_CASE.RECORD_ACTIVE.eq(true))                                                                                                                                     
.orderBy(USE_CASE.CREATED_ON.desc())                                                                                                                                     
.limit(10)
.offset(0)                                                                                                                                                                                                
.fetch(new UseCaseMapper()))

这就像 postgres 的魅力,但在 mssql 上我们得到以下错误:

Execution exception[[CompletionException: org.jooq.exception.DataAccessException: 
SQL [select "park"."dbo"."use_case".* from "park"."dbo"."use_case" where
"park"."dbo"."use_case"."record_active" = ? 
order by "park"."dbo"."use_case"."created_on" desc limit ?]; 
Incorrect syntax near 'limit'.]]

我知道对于 mssql,等效查询类似于,

select top 10 * 
from use_case 
where record_active = true
order by created_on desc;

如何更改我的 java 代码以获取 mssql 中的限制记录?

【问题讨论】:

【参考方案1】:

正确SQLDialect

异常消息暗示您仍在使用 PostgreSQL(或其他一些非 SQL Server)方言,因为您的目录/架构/表/列使用 "double_quotes" 引用,而不是 [brackets]

在 SQL Server 上运行查询时,只需使用 SQLDialect.SQLSERVER。然后LIMIT 10 语法将正确转换为TOP 10

jOOQ 专业版 vs jOOQ 开源版

从我们发布的错误消息中,不太清楚您是如何真正配置 jOOQ 集成的,但如果您使用 DSL.using(Connection) 而不明确指定 SQLDialect,并且 jOOQ 不能正确“猜测”适当的SQLDialect,这主要是因为以下两个原因之一:

    您正在使用一些 jOOQ 无法识别的非标准 JDBC URL。因此,它使用 SQLDialect.DEFAULT,而不是为您生成错误的 SQL 语法。

    您使用的是 jOOQ 开源版 (Maven groupId org.jooq) 而不是 jOOQ 专业版 (Maven groupId org.jooq.pro,要手动安装,因为它不是通过 Maven Central 分发的),这也会使用SQLDialect.DEFAULT 导致jOOQ。

    注意:这也可能是偶然发生的,例如作为通过 Spring Boot 或其他已经依赖于 jOOQ 开源版的框架引入的传递依赖项。在这种情况下,您必须确保将传递依赖排除在您的类路径中。在 Maven 中,您可以使用 mvn dependency:tree 显示所有依赖项

【讨论】:

嗨卢卡斯,感谢您的回答!请注意,我们使用 org.jooq.pro 作为 maven 依赖项,从我在调试 JDBCUtils 时看到的情况是,连接 url 包含 ':sqlserver:' 方言,但返回的 SQLDialect 是 SQLDefault。 在调试过程中,我在方言方法中看到了/* [pro] */ 区域,而调试器并没有进入该区域......正如我已经提到的,我们使用的是 jOOQ 专业版(Maven groupId org.jooq.pro) 我相信不会是这样的...... 也许您的类路径中确实有 jOOQ 开源版?请检查您是否还意外地从某处导入了org.jooq(例如使用mvn dependency:tree)。例如,Spring Boot 具有您需要排除的 jOOQ 开源版依赖项。两个版本的所有包/类名都相同,但内容不同。 再次感谢,我使用的是 simpleflatmapper (sfm-jooq),它还导入了开源 org.jooq 的依赖项。排除它后,它就像一个魅力! @kostia:啊,很高兴知道!我已经创建了一个问题来创建传递依赖 provided,或者记录如何明确排除它:github.com/arnaudroger/SimpleFlatMapper/issues/659

以上是关于Jooq 与 SQL Server 如何选择前 N 个结果的主要内容,如果未能解决你的问题,请参考以下文章

在 SQL Server 中,如何选择前 4 行?

将 JooQ 与 SQL Server 一起使用,getTables() 方法返回服务器上所有数据库中的所有表

jOOQ:如何在选择查询中调用 Sql 用户定义函数

SQL Server如何编辑超过前200行的数据

SQL Server 2017 - 使用 Gradle 生成 JOOQ 代码

Information_schema 未从 jooq for SQL Server 生成