【问题标题】:Do several modify operations at once一次做几个修改操作
【发布时间】:2017-06-19 20:05:12
【问题描述】:

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

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;

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

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;

在我看来这是正确的,但显然我错过了一些东西。还是在oracle xquery中做不到?

给出的错误信息:

ORA-19114:XPST0003 - 解析 XQuery 表达式时出错: LPX-00801:“复制”7 复制 $i := $p modify( - ^ ORA-06512:第 5 行

【问题讨论】:

    标签: oracle xquery xquery-sql


    【解决方案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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-31
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-28
      相关资源
      最近更新 更多