一次做几次修改操作

时间:2017-06-19 20:05:13

标签: oracle xquery xquery-sql

在下面的代码中,首先需要添加一个元素,在代码的其余部分中创建或更新一个名为t的属性。

-L=/mnt/pi-rootfs/opt/vc/lib

我的问题是我想将这两个修改加入到这样的一个xquery调用中

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;

在我脑海中,这是正确的,但显然我错过了一些东西。或者它无法在oracle xquery中完成?

给出的错误消息:

  

ORA-19114:XPST0003 - 解析XQuery表达式时出错:   LPX-00801:&#39;复制&#39; XQuery语法错误7副本$ i:= $ p modify(    - ^ ORA-06512:em line 5

1 个答案:

答案 0 :(得分:1)

您可以在一个修改子句中组合这两个操作:

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.

无论是否存在t属性,其结果与原始广告块的结果相同。

顺便提一下,您目前依赖NLS会话设置将时间戳格式化为字符串;明确地做它会更好,例如。

...
    ' 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;

获得类似

的输出
<log t="2017-06-19T21:28:54.896506"><update data="2017-06-19T21:28:54.896506"/></log>