2017-06-19 3 views
0

Im folgenden Code muss zuerst ein Element hinzugefügt werden, im restlichen Code wird ein Attribut namens t erstellt oder aktualisiert.Mehrere Operationen gleichzeitig bearbeiten

declare 
    LOG_REFERENCE xmltype:=xmltype('<log />'); 
begin 

    select XMLQuery(' 
    copy $p := $p1 modify insert node <update data="{$p2}" /> 
       as last into $p/log 
    return $p 
    ' PASSING LOG_REFERENCE AS "p1", to_char(systimestamp) AS "p2" RETURNING CONTENT) 
     INTO LOG_REFERENCE from dual; 

    select XMLQuery(' 
    copy $i := $p1 modify(
     if (fn:exists($i/log[1]/@t)) then (
     replace value of node $i/log[1]/@t with $p2 
    ) else (
     insert node attribute t {$p2} into $i/log[1] 
    ) 
    ) 
    return $i 
    ' PASSING LOG_REFERENCE AS "p1", to_char(systimestamp) AS "p2" RETURNING CONTENT) 
     INTO LOG_REFERENCE from dual; 

    dbms_output.PUT_LINE(LOG_REFERENCE.getClobVal()); 
end; 

Mein Problem ist, dass ich die beiden ändern in eine xquery Aufruf wie dieses

declare 
    LOG_REFERENCE xmltype:=xmltype('<log />'); 
begin 

    select XMLQuery(' 
    copy $p := $p1 modify(
    insert node <update data="{$p2}" /> 
       as last into $p/log 
    ) 

    copy $i := $p modify(
     if (fn:exists($i/log[1]/@t)) then (
     replace value of node $i/log[1]/@t with $p2 
    ) else (
     insert node attribute t {$p2} into $i/log[1] 
    ) 
    ) 

    return $i 
    ' PASSING LOG_REFERENCE AS "p1", to_char(systimestamp) AS "p2" RETURNING CONTENT) 
     INTO LOG_REFERENCE from dual; 

    dbms_output.PUT_LINE(LOG_REFERENCE.getClobVal()); 
end; 

In meinem Kopf das ist richtig, aber natürlich im, fehlt etwas beitreten wollten. Oder es kann nicht in Orakel Xquery getan werden?

die Fehlermeldung, die gegeben wurde:

ORA-19114: XPST0003 - Fehler den XQuery-Ausdrucks bei der Analyse: LPX-00801: XQuery Syntaxfehler bei 'Kopie' 7 Kopie $ i: = $ p ändern ( -^ORA-06512: em Linie 5

Antwort

1

Sie beiden Vorgänge in einer einzigen ändern Klausel kombinieren:

declare 
    LOG_REFERENCE xmltype:=xmltype('<log />'); 
begin 

    select XMLQuery(' 
    copy $p := $p1 modify(
    insert node <update data="{$p2}" /> 
       as last into $p/log, 
     if (fn:exists($p/log[1]/@t)) then (
     replace value of node $p/log[1]/@t with $p2 
    ) else (
     insert node attribute t {$p2} into $p/log[1] 
    ) 
    ) 

    return $p 
    ' PASSING LOG_REFERENCE AS "p1", to_char(systimestamp) AS "p2" RETURNING CONTENT) 
     INTO LOG_REFERENCE from dual; 

    dbms_output.PUT_LINE(LOG_REFERENCE.getClobVal()); 
end; 
/

<log t="19-JUN-17 21.25.56.434586 +01:00"><update data="19-JUN-17 21.25.56.434586 +01:00"/></log> 

PL/SQL procedure successfully completed. 

Das scheint das gleiche Ergebnis wie Ihr ursprünglicher Block zu erhalten, mit oder ohne ein vorhandenes t Attribut.

Übrigens verlassen Sie sich derzeit auf Ihre NLS-Session-Einstellungen, um den Zeitstempel als String zu formatieren; es wäre besser, dies explizit zu tun, z.B.

... 
    ' PASSING LOG_REFERENCE AS "p1", 
     to_char(systimestamp, 'YYYY-MM-DD"T"HH24:MI:SS.FF6') AS "p2" 
     RETURNING CONTENT) 
     INTO LOG_REFERENCE from dual; 

eine Ausgabe wie

<log t="2017-06-19T21:28:54.896506"><update data="2017-06-19T21:28:54.896506"/></log> 
zu erhalten
Verwandte Themen