使用jOOQ 3.11.2和Postgres 9.4,我试图在第二个CTE的定义中重新使用一个jOOQ CTE。
根据StackOverflow的问题,以下内容是不正确的 如何在jOOQ中的另一个CTE中重复使用一个CTE。
CommonTableExpression<...> cteTwo = name().fields().as(select( with(cteOne ... ).from(cteOne) );
根据上面的回答,我完全省略了cteTwo中的with(cteOne)子句。我试了一下。
import static org.jooq.impl.DSL.*;
CommonTableExpression<...> cteOne = name().fields().as(select(...);
CommonTableExpression<...> cteTwo = name().fields().as(select().from(cteOne) ); // seem to need with(cteOne) here.
List<someDTO> result = create
.with(cteOne)
.with(CteTwo)
.select(...)
.from(cteTwo)
.fetchInto(someDTO.class);
上面的代码编译后运行时出现错误:"jooq: bad SQL grammar. ... ERROR: relation \"cteOne\" does not exist.' 在生成的SQL中,在cteTwo中没有引用cteOne。
然后我试着把 with(cteOne)
子句在 cteTwo 定义内的不同地方。SELECT子句前只有三个地方可以尝试。都不正确。
CommonTableExpression<...> cteTwo = with(cteOne).name().fields().as(select( ... ).from(cteOne) );
CommonTableExpression<...> cteTwo = name() with(cteOne).fields().as(select( ... ).from(cteOne) );
CommonTableExpression<...> cteTwo = name().fields().with(cteOne).as(select( ... ).from(cteOne) );
请注意,这不同于定义几个CTE然后在最后的select语句中使用每个CTE,就像这样。
CommonTableExpression<...> cteAlpha = name(...).fields(...).as(select(...);
CommonTableExpression<...> cteBeta = name(...).fields(...).as(select(...);
List<SomeDTO> list = create
.with(cteAlpha)
.with(cteBeta)
.select(...) from(cteAlpha, cteBeta).fetchInto(SomeDTO.class);
我还没有找到关于这个精确点的文档或例子。应该怎么做呢?
我在回答自己的问题。从2020年1月1日起,不可能连锁CTE。正如我在评论中指出的,变通的办法是使用临时数据库表。在我的情况下,这是一个代码的味道。最后,我解决了更大的问题,简化了我的代码,不需要解决链式CTE的问题。
如果你确实使用了临时表,记得在不再需要的时候删除表,防止数据库混乱。
注意,jOOQ是一个维护良好的不断发展的库,在以后的版本中可能会增加这个功能。