我有3个表ABC是继承链的一部分:

  A
 / \
B   C


看起来像:

A(row_id)
B(row_id, a_row_id REFERENCES A(row_id))
C(row_id, a_row_id REFERENCES A(row_id))


请注意,列名称相同(a_row_id

现在,我通过执行以下操作来获取RecordBC

ctx.select()
    .from(
        Tables.A
        .leftOuterJoin(Tables.B).onKey()
        .leftOuterJoin(Tables.C).onKey()
    )
    .where(someCondition)
    .fetch()


我同时加入了BC,因为我(此时)不知道我要寻找哪个。

但是,当我知道我需要获取B并执行以下操作时:

ctx.select()
    .from(
        Tables.A
        .leftOuterJoin(Tables.B).onKey()
    )
    .where(someCondition)
    .fetch()


我得到一个Record,如果我执行record.field(Tables.B.A_ROW_ID).toString(),则得到"b.a_row_id",如果我执行record.getValue(Tables.B.A_ROW_ID),则得到期望值。

但是,如果我执行record.field(Tables.C.A_ROW_ID).toString(),则会得到"b.a_row_id",而record.getValue(Tables.C.A_ROW_ID)给我期望的record.getValue(Tables.B.A_ROW_ID)值。

我认为这是因为引用父表的列名称相同而引起的。

如果jOOQ是联接中的唯一表,它是否仅使用表的field_name(而不使用完全限定的“ table.field_name”)?

任何帮助,将不胜感激。

最佳答案

Record.field(Field)Record.field(Name)Record.field(String)的语义均遵循相同的一致逻辑:

在SQL中,记录的列具有名称。如果该名称源自表/视图(在架构(在目录中))中,则可以限定该名称,但这是可选的。不合格的列也很好,例如什么时候:


别名列
创建表达式,例如col + 1
如果某些列不合格,请使用JOIN .. USING
使用派生表(可能具有表名,但肯定没有模式/目录)
SELECT *与供应商特定的列发射运算符(例如PIVOTMODELMATCH_RECOGNIZE)一起使用。
等等。


如您所见,从语法角度来看,具有合格的列名是例外,而不是规则。因此,Record.field(Field)的最合理且最有用的实现是:


在记录中找到完全匹配的内容(完全限定的列名)
如果失败,请在记录内找到近似匹配项(不合格的列名)
如果那是“模棱两可”的(因为顶层选择允许这种模棱两可),则:


jOOQ 3.8+ logs a warning
jOOQ 4.0+ will throw an exception



因此,您观察到的行为是正确的。

关于java - jOOQ记录中的错误字段,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41429708/

10-13 05:25