[英]Update a non-schema XMLType column in Oracle 12c?
如果xmltype对象不是基于架构的,即在Oracle数据库外部生成的,是否有任何方法可以更新Oracle 12c中的XMLType列? 我正在尝试只更新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;
您的触发器正在验证架构。 您的示例XML没有架构。 假设您的真实XML实际上并没有您已省略的架构并且该更新正在删除,那么大概是在创建触发器之前将其插入到表中。
您似乎有三个选择:
更新XML以包括有效模式。
删除触发器。
修改触发器以跳过对非架构XML的验证:
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;
但这并不能阻止将现有的基于架构的值更新为基于非架构的值。
您的更新语句有效,但不影响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;
我已经使用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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.