更新Oracle 12c中的非架构XMLType列?

时间:2017-08-11 09:59:20

标签: xml oracle plsql

如果xmltype对象不是基于模式的,那么有没有办法在Oracle 12c中更新XMLType列 - 即它是在Oracle数据库之外生成的?我正在尝试更新Oracle数据库中一个XML记录中的一个字段。对于一个简单的xml,例如:

<a>
  <b>
    <c>
      <d1>foo</d1>
      <d2>bar</d2>
       ...
    </c>
  </b>
</a>

我想将d1字段中的文字从foo更改为newText。因此我尝试过:

UPDATE myXmlTable
  SET myXmlColumn = updatexml(myXmlColumn ,
                              '/a/text()',
                              updatexml(extract(myXmlColumn , '/a/ *'),
                                        'b/c/d1/text()',
                                        'newText')
                              )

  WHERE rowid = 'AAAHUBAAoAAAA0SAAA';

但是我得到了错误:

SQL Error: ORA-19030: Method invalid for non-schema based XML Documents.
ORA-06512: at "SYS.XMLTYPE", line 354
ORA-06512: at "DIC_OWNER.XML_TRIG", line 8
ORA-04088: error during execution of trigger 'DIC_OWNER.XML_TRIG'
19030. 00000 -  "Method invalid for non-schema based XML Documents."
*Cause:    The method can be invoked on only schema based xmltype objects.
*Action:   Don't invoke the method for non schema based xmltype objects.

如何将我的代码概括为适用于非架构xml文件?

[编辑] 以下是正在使用的触发器 - 我没有创建此

create or replace trigger xml_trig before insert
or update on myXmlTable
for each row

declare

  newxml XMLType;

begin

  newxml := :new.OBJECT_VALUE;
  XMLType.schemavalidate(newxml);

end;

1 个答案:

答案 0 :(得分:2)

您的触发器正在验证架构。您的示例XML没有架构。假设您的真实XML实际上没有您已经省略的架构并且更新正在删除,那么它可能会在创建触发器之前插入到表中。

您似乎有三种选择:

  1. 更新XML以包含有效的架构。

  2. 删除触发器。

  3. 修改触发器以跳过非架构XML的验证:

  4. create or replace trigger xml_trig
    before insert or update on myXmlTable
    for each row
    begin
      if :new.myxmlcolumn.isschemabased() = 1 then
        XMLType.schemavalidate(:new.myxmlcolumn);
      end if;
    end;
    /
    

    或者,如果您想确保所有新条目 基于架构,只需检查更新:

      if inserting or :new.myxmlcolumn.isschemabased() = 1 then
        XMLType.schemavalidate(:new.myxmlcolumn);
      end if;
    

    但这并不妨碍将现有的基于模式的值更新为基于非模式的值。