SQL Server编译含CASE分组的Prepared Statement是否存在已知问题?
关于SQL Server中JOOQ生成CASE表达式分组的Prepared Statement报错问题
我尝试用CASE表达式实现分组,基于sakila数据库用JOOQ编写了如下Kotlin代码(因Kotlin语法冲突,需转义when和as),生成的SQL符合预期:
val shared = `when`(ACTOR.LAST_NAME.like("A%"), "A") .`when`(ACTOR.LAST_NAME.like("B%"), "B") .otherwise("C") val r = ctx.select( count(), shared.`as`("code") ) .from(ACTOR) .groupBy(shared) .fetch()
但在SQL Server 2017 Express(v14)上执行时报错:
Column 'DTB_DEV_SAKILA.dbo.actor.last_name' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
奇怪的是,将栈跟踪中输出的SQL语句里的Prepared Statement占位符?替换为实际值后,在SSMS中可正常执行:
select count(*), case when [DTB_DEV_SAKILA].[dbo].[actor].[last_name] like 'A%' then 'A' when [DTB_DEV_SAKILA].[dbo].[actor].[last_name] like 'B%' then 'B' else 'C' end as code from [DTB_DEV_SAKILA].[dbo].[actor] group by case when [DTB_DEV_SAKILA].[dbo].[actor].[last_name] like 'A%' then 'A' when [DTB_DEV_SAKILA].[dbo].[actor].[last_name] like 'B%' then 'B' else 'C' end as code
注意事项
- 使用JOOQ的
inline()函数移除绑定变量后,代码可正常运行; - 改用IIF替代CASE WHEN仍会出现相同报错。
另外,仅基于列引用的分组代码能正常执行:
val shared = length(ACTOR.LAST_NAME) val r = ctx.select( count(), shared.`as`("voluminousness") ) .from(ACTOR) .groupBy(shared) .fetch()
据此推测问题出在编译包含CASE语句分组的Prepared Statement时,这更像是JDBC/SQL Server的问题而非JOOQ的问题。想了解JOOQ用户有没有其他实现方式、可行的解决方法,以及其他数据库是否存在这类CASE分组限制。
环境:JOOQ 3.19.10,MS JDBC 12.8.1.jre11,SQL Server 2017(v14.0.2065)
内容的提问来源于stack exchange,提问作者David Bullock
相关产品推荐
相关产品推荐

