Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否在Oracle 12c中更新非架构XMLType列?_Xml_Oracle_Plsql - Fatal编程技术网

是否在Oracle 12c中更新非架构XMLType列?

是否在Oracle 12c中更新非架构XMLType列?,xml,oracle,plsql,Xml,Oracle,Plsql,如果XMLType对象不是基于模式的(即,它是在Oracle数据库之外生成的),有没有办法更新Oracle 12c中的XMLType列?我试图只更新Oracle数据库中一条XML记录中的一个字段。对于简单的xml,例如: <a> <b> <c> <d1>foo</d1> <d2>bar</d2> ... </c> </b> &l

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

<a>
  <b>
    <c>
      <d1>foo</d1>
      <d2>bar</d2>
       ...
    </c>
  </b>
</a>
然而,我得到的错误是:

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;

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

你似乎有三个选择:

  • 更新XML以包含有效的架构

  • 卸下扳机

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

  • 或者,如果要确保所有新条目都基于架构,请仅在更新时执行该检查:

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

    但这并不阻止现有的基于架构的值更新为非基于架构的值。

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

    你似乎有三个选择:

  • 更新XML以包含有效的架构

  • 卸下扳机

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

  • 或者,如果要确保所有新条目都基于架构,请仅在更新时执行该检查:

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

    但这并不阻止现有的基于模式的值被更新为非基于模式的值。

    update语句可以工作,但不会影响xml。如果删除多余的第二个UPDATEXML,它将执行它应该执行的操作

    CREATE TABLE myXmlTable (myXmlColumn XMLTYPE);
    
    INSERT INTO myXmlTable (myXmlColumn) VALUES (XMLTYPE('<a>
                                                            <b>
                                                              <c>
                                                                <d1>foo</d1>
                                                                <d2>bar</d2>
                                                                 ...
                                                              </c>
                                                            </b>
                                                          </a>'));
    
    COMMIT; 
    
    UPDATE myXmlTable
    SET myXmlColumn = updatexml(myXmlColumn,
                              'a/b/c/d1/text()',
                                        'newText'),
    COMMIT;
    
    SELECT XMLSERIALIZE(DOCUMENT myXmlColumn INDENT)
    FROM myXmlTable;
    
    创建表myXmlTable(myXmlColumn XMLTYPE);
    在myXmlTable(myXmlColumn)中插入值(XMLTYPE('
    福
    酒吧
    ...
    '));
    犯罪
    更新myXmlTable
    设置myXmlColumn=updatexml(myXmlColumn,
    “a/b/c/d1/text()”,
    “新文本”),
    犯罪
    选择XMLSERIALIZE(文档myXmlColumn缩进)
    从myXmlTable;
    

    我已经用Oracle 11.2对此进行了测试。

    您的update语句可以工作,但不会影响xml。如果删除多余的第二个UPDATEXML,它将执行它应该执行的操作

    CREATE TABLE myXmlTable (myXmlColumn XMLTYPE);
    
    INSERT INTO myXmlTable (myXmlColumn) VALUES (XMLTYPE('<a>
                                                            <b>
                                                              <c>
                                                                <d1>foo</d1>
                                                                <d2>bar</d2>
                                                                 ...
                                                              </c>
                                                            </b>
                                                          </a>'));
    
    COMMIT; 
    
    UPDATE myXmlTable
    SET myXmlColumn = updatexml(myXmlColumn,
                              'a/b/c/d1/text()',
                                        'newText'),
    COMMIT;
    
    SELECT XMLSERIALIZE(DOCUMENT myXmlColumn INDENT)
    FROM myXmlTable;
    
    创建表myXmlTable(myXmlColumn XMLTYPE);
    在myXmlTable(myXmlColumn)中插入值(XMLTYPE('
    福
    酒吧
    ...
    '));
    犯罪
    更新myXmlTable
    设置myXmlColumn=updatexml(myXmlColumn,
    “a/b/c/d1/text()”,
    “新文本”),
    犯罪
    选择XMLSERIALIZE(文档myXmlColumn缩进)
    从myXmlTable;
    

    我已经用Oracle 11.2对此进行了测试。

    您可以简化您的声明:

    样本数据

    CREATE TABLE yourtable ( yourxmlcolumn ) AS
      SELECT XMLTYPE( '<a><b><c><d1>foo</d1><d2>bar</d2></c></b></a>' ) FROM DUAL;
    
    UPDATE yourtable
    SET yourxmlcolumn = UPDATEXML(
                          yourxmlcolumn,
                          '/a/b/c/d1/text()',
                          'newText'
                        );
    
    UPDATEDXML
    -------------------------------------------------
    <a><b><c><d1>newText</d1><d2>bar</d2></c></b></a>
    
    输出

    CREATE TABLE yourtable ( yourxmlcolumn ) AS
      SELECT XMLTYPE( '<a><b><c><d1>foo</d1><d2>bar</d2></c></b></a>' ) FROM DUAL;
    
    UPDATE yourtable
    SET yourxmlcolumn = UPDATEXML(
                          yourxmlcolumn,
                          '/a/b/c/d1/text()',
                          'newText'
                        );
    
    UPDATEDXML
    -------------------------------------------------
    <a><b><c><d1>newText</d1><d2>bar</d2></c></b></a>
    
    UPDATEDXML
    -------------------------------------------------
    newTextbar
    
    您可以简化您的陈述:

    样本数据

    CREATE TABLE yourtable ( yourxmlcolumn ) AS
      SELECT XMLTYPE( '<a><b><c><d1>foo</d1><d2>bar</d2></c></b></a>' ) FROM DUAL;
    
    UPDATE yourtable
    SET yourxmlcolumn = UPDATEXML(
                          yourxmlcolumn,
                          '/a/b/c/d1/text()',
                          'newText'
                        );
    
    UPDATEDXML
    -------------------------------------------------
    <a><b><c><d1>newText</d1><d2>bar</d2></c></b></a>
    
    输出

    CREATE TABLE yourtable ( yourxmlcolumn ) AS
      SELECT XMLTYPE( '<a><b><c><d1>foo</d1><d2>bar</d2></c></b></a>' ) FROM DUAL;
    
    UPDATE yourtable
    SET yourxmlcolumn = UPDATEXML(
                          yourxmlcolumn,
                          '/a/b/c/d1/text()',
                          'newText'
                        );
    
    UPDATEDXML
    -------------------------------------------------
    <a><b><c><d1>newText</d1><d2>bar</d2></c></b></a>
    
    UPDATEDXML
    -------------------------------------------------
    newTextbar
    
    异常是由触发器引发的,而不是更新本身;那么触发器在做什么呢?很抱歉,由于某些原因,我没有添加完整的错误消息,我现在已经编辑了帖子。这似乎是一个SQL错误。我没有使用任何触发器。该触发器中的
    schemavalidate()
    过程调用对非架构XML无效。要么您正在更新的XML确实有一个模式,而您的更新正在以某种方式丢失它,要么更有可能是在触发器强制模式验证之前创建的行?是否已将正在使用的触发器添加到问题中?异常是由您的触发器引发的,而不是更新本身;那么触发器在做什么呢?很抱歉,由于某些原因,我没有添加完整的错误消息,我现在已经编辑了帖子。这似乎是一个SQL错误。我没有使用任何触发器。该触发器中的
    schemavalidate()
    过程调用对非架构XML无效。或者您正在更新的XML确实有一个模式,但您的更新正在以某种方式丢失它,或者更有可能是在触发器强制执行模式验证之前创建的行?已将正在使用的触发器添加到问题中谢谢。重新编写触发器解决了问题。谢谢。重新编写触发器解决了问题。