我有3个表A
,B
和C
是继承链的一部分:
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
)现在,我通过执行以下操作来获取
Record
和B
的C
:ctx.select()
.from(
Tables.A
.leftOuterJoin(Tables.B).onKey()
.leftOuterJoin(Tables.C).onKey()
)
.where(someCondition)
.fetch()
我同时加入了
B
和C
,因为我(此时)不知道我要寻找哪个。但是,当我知道我需要获取
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 *
与供应商特定的列发射运算符(例如PIVOT
,MODEL
,MATCH_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/