2016-04-20 4 views
2

Es fühlt sich an, als ob ich in der Nähe bin, aber ich kann nicht herausfinden, wie man etwas wie das unten in jooq tut.jooq MERGE In Oracle

MERGE INTO USER_ASSIGNMENTS ua 
USING (
      SELECT core_object_id 
      FROM core_objects 
      WHERE exists(SELECT * 
         FROM LKU_CODE lc JOIN LKU_CODE_TYPE lct 
           ON lc.LKU_CODE_TYPE_ID = lct.LKU_CODE_TYPE_ID AND lct.CODE_TYPE = 'OBJECT_TYPE' AND 
            lc.CODE = 'PORTFOLIOS' 
         WHERE lc.LKU_CODE_ID = core_objects.OBJECT_TYPE_ID) AND object_id = 83 
    ) "co" 
ON (ua.CORE_OBJECT_ID = "co".CORE_OBJECT_ID AND USER_ID = 24 AND SECTION = 1) 
WHEN MATCHED THEN UPDATE 
SET create_date = sysdate, created_by = '24', capabilities = 12 
    WHERE capabilities <> 12 
WHEN NOT MATCHED THEN INSERT 
    (CAPABILITIES, CORE_OBJECT_ID, CREATE_DATE, CREATED_BY, SECTION, USER_ID) 
VALUES (5, "co".CORE_OBJECT_ID, sysdate, '24', 1, 24); 

Die große Sache zu beachten ist, dass ich versuche, den Wert durch die Verwendung zurückgegeben zu verwenden, also muss ich alias es und.values() ein Feld Anruf anzunehmen hat. Ich denke, ich kann um das .values() Problem mit dem .values(Collection<?>) Anruf, Bündel Dinge, einschließlich dieses Feld, in eine Sammlung, so dass ich denke, dass ich diesen Teil haben. Was mich betrifft ist, dass ich einen .as() Anruf nach .using() nicht tun kann. Wenn ich die USING Abfrage eine "Tabelle" über .asTable(), die Bereitstellung eines Alias, wird das lassen Sie mich das Feld aufrufen? Hier ist ein bisschen von dem, was ich im Moment haben:

Table<Record1<BigDecimal>> usingStatement = readContext 
     .select(_co.CORE_OBJECT_ID) 
     .from(_co) 
     .where(DSL.exists(readContext.select(_lc.fields()).from(
       _lc.join(_lct).onKey(Keys.LC_LCT___FK) 
         .and(_lc.CODE.equal(capability.getObjectTypeCode())) 
         .and(_lct.CODE_TYPE.equal(LkuCodeTypeLookup.OBJECT_TYPE))))).asTable("sdf"); 
... 

return writeContext 
        .mergeInto(_ua) 
        .using(usingStatement) 
        .on(sectionalConditions.and(_ua.CORE_OBJECT_ID.equal(coidField))) 
        .whenMatchedThenUpdate() 
        .set(_ua.CREATE_DATE, time) 
        .set(_ua.CREATED_BY, creator) 
        .set(_ua.CAPABILITIES, capabilities) 
        .where(_ua.CAPABILITIES.notEqual(capabilities)) 
        .whenNotMatchedThenInsert(_ua.CAPABILITIES, _ua.CORE_OBJECT_ID, _ua.CREATE_DATE, 
          _ua.CREATED_BY, _ua.SECTION, _ua.USER_ID) 
        .values(capabilities, gcoid, time, creator, section, uuid).execute(); 

A „gerade merge“ mit Dual ist einfach in jOOQ, aber ich würde versuchen möchte, dass in der Zusammenführung wählen zu kombinieren Abfragen zu speichern und lassen Sie die DB tue, was es am besten kann, also versuche ich, core_object_id nicht in einer anderen Abfrage zu haben, wenn möglich.

Antwort

2

Das Aliasing passiert wirklich auf der Tabelle (d. H. Die Auswahl), nicht auf einem Artefakt, das durch die USING-Klausel zurückgegeben wird. Zumindest modelliert jOOQ es so. Sie haben Ihre usingStatement Variable bereits korrekt formatiert. Alles was Sie jetzt tun müssen, ist dereferenzieren die gewünschte Spalte aus es, z.B .:

usingStatement.field(_co.CORE_OBJECT_ID); 

Diese für die Spalte CORE_OBJECT_ID in der usingStatement Tabelle mit dem Namen suchen.

+0

Freaking genial! Vielen Dank! – DanO

+1

(und das Dereferenzierungsstück ist ein neues Nugget, von dem ich nicht wusste, dass ich es tun könnte - ich kann das anstelle dieser verrückten Doppelfeld-Sache in meinem anderen Beitrag verwenden; vielen Dank für die Hilfe und das Werkzeug!) – DanO

+0

@DanO: Gern geschehen! :) –