我将 jOOQ 与 Kotlin 和 PostgreSQL 一起使用。
我已将一个字段定义为变量。 我想在 SELECT 语句和 ORDER BY 子句中使用此变量。 但是,在 ORDER BY 子句中,我使用它来计算要排序的值。
jOOQ 在这里遇到了一个问题,因为它只使用字段名称,如果我只按字段排序而不使用它来计算新字段,那么该字段名称就可以工作。
这是一个最小的例子:
val field = ACTOR.ACTOR_ID.`as`("my_actor_id")
ctx
.select(ACTOR.LAST_NAME, field)
.from(ACTOR)
.orderBy(field.plus(1))
.fetch()
这会引发异常:
org.jooq.exception.DataAccessException: SQL [select
"public"."actor"."last_name",
"public"."actor"."actor_id" as "my_actor_id"
from "public"."actor"
order by ("my_actor_id" + ?)]; ERROR: column "my_actor_id" does not exist
如果我只按像这样存储为变量的字段进行排序,一切都会按预期进行:
ctx
.select(ACTOR.LAST_NAME, field)
.from(ACTOR)
.orderBy(field)
.fetch()
因为这个使用字段名称的查询是有效的:
select
"public"."actor"."last_name",
"public"."actor"."actor_id" as "my_actor_id"
from "public"."actor"
order by "my_actor_id"
我本来期望 jOOQ 意识到,该字段在 ORDER BY 子句中没有被它自己使用,因此必须使用该字段的定义而不是其别名。
我当前的解决方法如下所示:
val fieldWithoutAlias = ACTOR.ACTOR_ID
val field = fieldWithoutAlias.`as`("my_actor_id")
ctx
.select(ACTOR.LAST_NAME, field)
.from(ACTOR)
.orderBy(fieldWithoutAlias.plus(1))
.fetch()
有没有更好的方法告诉jOOQ使用字段定义而不是别名?
我的假设是否正确,jOOQ 没有检测到必须在此处使用字段定义而不是其名称?
从 jOOQ 3.19 开始,此主题有一个已知问题:
您已经找到了解决方法,所以现在就使用它。
我本来期望 jOOQ 意识到,该字段在 ORDER BY 子句中没有被它自己使用,因此必须使用该字段的定义而不是其别名。
这是特定于方言的。许多方言支持在
ORDER BY
表达式中渲染投影别名。没有充分的理由不这样做,根据 SQL 中SELECT
操作的逻辑顺序,语义是清楚的,但显然,如果已知一种方言不支持这种语法,那么 jOOQ 可以通过替换来模拟它其定义的别名。
默认情况下,别名始终呈现其别名引用,而不是其声明,另请参阅手册中有关声明与引用的部分。