java - 使用 JOOQ DSL API 在 VALUES() 上加入表
问题描述
笔记:
我有一个类似的问题悬而未决,如何生成以下问题
SQL
,JOOQ
但在过去的两天里,我解决了 99% 的问题,这给我带来了另一个问题——这里描述了这个问题——因为我目前的解决方案没有回答我最初的问题删除了另一个问题并创建了这个新问题 - 而不是替换原来的问题。更新:将此问题更改为解决方案,正如 Lukas Eder 指出的那样,生成的 SQL 是有效的。谢谢。
我有以下SQL
查询 - 作为示例并将其转换为为不同的表JOOQ
API
生成:SQL
SELECT c.*
FROM contacts c
JOIN (
VALUES
(0, 13259),
(1, 12472),
(2, 12422)
) AS il(listindex, id) ON c.id = il.id
ORDER BY il.listindex;
我根据和的手册创建了以下JOOQ
代码VALUES()
JOIN
笔记:
这是一个独立的示例,它从字符串创建表、字段和名称。这些代码实际上都没有在数据库中执行,它只是生成
SQL
import static org.jooq.impl.DSL.row;
import static org.jooq.impl.DSL.values;
import static org.jooq.impl.DSL.table;
import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.name;
import org.jooq.DSLContext;
import org.jooq.Field;
import org.jooq.Name;
import org.jooq.Record;
import org.jooq.Row2;
import org.jooq.SQLDialect;
import org.jooq.SelectJoinStep;
import org.jooq.Table;
import org.jooq.impl.DSL;
public class StackoverflowJOOQQuestion {
public static void main(String[] args) {
DSLContext ctx = DSL.using(SQLDialect.H2);
// create test data (as in the sql statement on top)
Long[] lon = new Long[] { 13259l, 12472l, 12422l };
Row2<Integer, Long>[] rows = new Row2[lon.length];
for (int i = 0; i < rows.length; i++) {
rows[i] = row(i, lon[i]);
}
// create Names, Fields and Tables
// contacts table
Name contactIdName = name("tContacts", "conIdContact");
Field contactIdField = field(contactIdName, Long.class);
Name contactNameName = name("tContacts", "conContactName");
Field contactNameField = DSL.field(contactNameName, String.class);
// values table
Name nameTableValues = name("il");
Table valuesTable = table(nameTableValues);
Name nameTableValuesIndex = name("il", "listindex");
Field valuesIndexField = field(nameTableValuesIndex, Integer.class);
Name nameTableValuesId = name("il", "id");
Field valuesIdField = field(nameTableValuesId, Long.class);
// build the SQL query
SelectJoinStep<Record> step = ctx.select(contactNameField).from("tContacts")
.join(//
values(rows)//
// NOTE: also works with Strings, Names or Table and
// Fields as shown here
// .as("il", "listindex", "id")//
// .as(nameTableValues, nameTableValuesIndex, nameTableValuesId)//
.as(valuesTable, valuesIndexField, valuesIdField)//
).on(contactIdField.eq(valuesIdField));
// print the query
System.out.println(step.getSQL());
}
}
但这会产生以下输出:
select "tContacts"."conContactName" from tContacts join (
(select null "listindex", null "id" where 1 = 0) union all
(select * from (
values (cast(? as int), cast(? as bigint))
, (cast(? as int), cast(? as bigint))
, (cast(? as int), cast(? as bigint))
) "il")
) "il" on "tContacts"."conIdContact" = "il"."id"
解决方案
这不是错误,您生成的 SQL 也没有问题。您要加入的派生表确实具有所需的列名。观察:
(select null "listindex", null "id" where 1 = 0) union all ...
对于某些数据库,在使用派生列列表功能时会应用仿真。看:
- https://github.com/jOOQ/jOOQ/issues/1801
- 如何将派生列列表(表和列别名)应用于 SQL Server 中的表值函数调用
- https://blog.jooq.org/2013/01/07/simulating-the-sql-standard
直到最近,H2 数据库才添加了对派生列列表功能的支持,因此 jOOQ 生成的 SQL 可能已经过时:
- http://h2database.com/html/grammar.html#table_expression
- https://github.com/h2database/h2database/pull/909
- https://github.com/h2database/h2database/commit/db1612f4241317e70f3da3930457d936eb24a67b
但是出于向后兼容性的原因,已经转向新的语法是不明智的。
鉴于 H2 没有定义明确的主要版本控制方案,jOOQ 也不区分 H2 方言。
推荐阅读
- python - def subplot(plt, (Y, X), (sz_y, sz_x) = (10, 10)): throws invalid syntax in Python 3
- django - Running Daphne with DotEnv in a systemd service
- windows - Git command not recognized even after installing NPM packages
- python - 'make' is not recognized as an internal or external command
- reactjs - 下一个 JS 图像,我无法使用顺风使图像位置居中
- r - R vlookup 基于最接近的数值变量
- html - 为 aspnet core 中的视图导出或使用 adobe xd 文件
- javascript - Scroll-Snap 滚动时如何阻止用户滚动?
- r - R Shiny / Leaflet 中的时间序列叶绿素
- javascript - 合并两个对象数组并根据对象内部存在的键更新对象