2017-01-02 1 views
2

Ich habe 3 Tabellen A, B und C, die Teil einer Vererbungskette sind:Fehlerhafte Feld in jOOQ Bilanz

A 
/\ 
B C 

und wie folgt aussehen:

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

Beachten Sie, dass die Spaltennamen sind selbe (a_row_id)

Jetzt hole ich Record s von B und C by doing:

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

Ich schließe ich über beide B und C, weil ich nicht (an dieser Stelle) wissen, welche ich suche.

Aber, wenn ich weiß, ich brauche B zu holen und dies zu tun:

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

Ich bekomme eine Record, auf dem, wenn ich record.field(Tables.B.A_ROW_ID).toString() tun, ich "b.a_row_id" bekommen, und wenn ich record.getValue(Tables.B.A_ROW_ID) bekomme ich den erwarteten Wert .

jedoch Wenn ich record.field(Tables.C.A_ROW_ID).toString() tun, erhalte ich "b.a_row_id" und record.getValue(Tables.C.A_ROW_ID) gibt mir den erwarteten Wert von record.getValue(Tables.B.A_ROW_ID).

Ich denke, das passiert, weil die Spaltennamen, die sich auf die Elterntabelle beziehen, gleich sind.

Verwendet jOOQ nur den Feldnamen der Tabelle (und nicht den vollqualifizierten "table.field_name"), wenn das die einzige Tabelle im Join ist?

Jede Hilfe zu diesem würde sehr geschätzt werden.

Antwort

1

Die Semantik Record.field(Field), Record.field(Name) und Record.field(String) alle gleich, konsistente Logik folgen: Spalte

In SQL, ein Rekord hat einen Namen. Dieser Name kann qualifiziert werden, wenn er aus einer Tabelle/View stammt (in einem Schema (in einem Katalog)), aber das ist optional. Nicht qualifizierte Spalten sind auch völlig in Ordnung, z. wenn:

  • die Spalte
  • Erstellen von Ausdrücken Aliasing, wie col + 1
  • Mit JOIN .. USING, bei denen Spalten
  • Mit abgeleiteten Tabellen nicht qualifiziert (die einen Tabellennamen haben, aber sicher kein Schema/Katalog)
  • mit SELECT * mit herstellerspezifischen, Spalte emittierenden Operatoren wie PIVOT, MODEL, MATCH_RECOGNIZE.
  • Etc.

Wie Sie aus einer Syntax Perspektive sehen können, sind mit qualifizierten Spaltennamen die Ausnahme, nicht die Regel.Somit ist die vernünftigste und allgemein nützliche Implementierung von Record.field(Field) ist:

  • Finden Sie das genaue Spiel innerhalb des Datensatz (vollständig qualifizierter Spaltenname)
  • Wenn das fehlschlägt, finden Sie das ungefähre Spiel innen der Datensatz (unqualifizierter Spaltenname)
  • Wenn die „mehrdeutig“ ist (weil die oberste Ebene wählt ermöglichen solche Mehrdeutigkeit), dann gilt:

Also, das Verhalten, das Sie beobachtet haben, ist richtig.

1

Lukas hat die Hauptfrage schon beantwortet, aber ich wollte Ihnen nur mitteilen, dass jOOQ am Ende eine SQL-Anweisung ausführt. Es ist begrenzt für Sicherheit und Caching, aber es ist immer noch eine SQL-Anweisung. Sie können das SQL selbst sehen, wenn Sie die Protokollierung starten.
Wenn Sie einen dynamischen Datensatz zurückgeben möchten und Spalte X sein soll, können Sie immer .as ("X") verwenden, um das Zurücklesen der Daten zu erleichtern.