Oracle:如何创建从XMLType提取数据的快速刷新物化视图?

Oracle:如何创建从XMLType提取数据的快速刷新物化视图?,oracle,materialized-views,xmltype,extract-value,Oracle,Materialized Views,Xmltype,Extract Value,我有一个包含两列的表xml\u documents:一个document\u id列(主键)和一个包含一些xml数据的xml列,这是一个无模式的XMLType。我可以仅使用文档id创建物化视图,方法如下: create materialized view mv refresh fast on commit as select document_id from xml_documents 这很好,但不是很有用。正如您所料,我希望物化视图从XML中提取数据,为此我使用extractValue()

我有一个包含两列的表
xml\u documents
:一个
document\u id
列(主键)和一个包含一些xml数据的
xml
列,这是一个无模式的
XMLType
。我可以仅使用
文档id
创建物化视图,方法如下:

create materialized view mv refresh fast on commit as 
select document_id
from xml_documents
这很好,但不是很有用。正如您所料,我希望物化视图从XML中提取数据,为此我使用
extractValue()
。我正在尝试以下方法:

create materialized view mv refresh fast on commit as 
select document_id, extractValue(xml, '/my/gaga') gaga
from xml_documents
这在以下情况下失败:

ORA-12054: cannot set the ON COMMIT refresh attribute for the materialized view
我应该如何创建一个从XML提取值的提交物化视图的快速刷新?

您的XML类型(可能)存储为CLOB。使用如下查询查找隐藏列:

select * from user_tab_cols where table_name = 'XML_DOCUMENTS';
然后创建一个函数将CLOB转换为XMLType,并提取值。请注意,“deterministic”关键字是必需的,尽管 我不知道为什么。在SQL和PL/SQL之间来回传递数据会很慢,但如果您使用的是物化视图,则情况可能会更糟 已经很慢了

create or replace function extract_from_clob(p_xml in clob) return varchar2 deterministic
  is
begin
    return XMLType(p_xml).extract('/my/gaga/text()').getStringVal();
end;
/
然后删除并创建物化视图,并将系统列传递到函数中:

create materialized view mv refresh fast on commit as 
select document_id, extract_from_clob(SYS_NC00003$) gaga
from xml_documents;
我不确定是否使用系统生成的隐藏列。这很管用,但似乎不是个好主意。至少它会成功的 很难在不同的系统上创建对象-每次都需要找到新的列名


当LOB工作正常时,XMLTypes不工作似乎很奇怪。我找不到任何关于这方面的文件;我不确定这是一个bug,一个未实现的特性,还是有一些神奇的设置可以让它工作。如果没有其他人能够提供更好的答案,那么在使用上述方法之前,您可能需要咨询Oracle支持部门。

哇,感谢您提供了这个令人惊讶的答案。我想我们已经很接近了,但是当我运行
创建物化视图…
时,我得到了一个
SQL错误:ORA-30625:不允许对NULL自参数进行方法调度
,我不确定如何绕过它。你知道吗?(原始表中的
xml
列被定义为
xmltype not null
,但这可能与此无关。)您究竟是如何创建表和物化视图日志的?以下是我使用的命令:
create table xml\u documents(document\u id number主键,xml xmltype not null)
使用主键在xml_文档上创建物化视图日志。这在10.2.0.1.0和11.2.0.1.0中对我起了作用。感谢您的跟进。我终于发现了问题所在:
/my/gaga
对于某些行不存在。因此我设想
extract()
返回
null
,因此应用
getStringVal()
会导致错误,Oracle不允许我创建物化视图。为了解决这个问题,我修改了您的
extract\u from\u clob()
测试以避免这个问题。我还添加了XPath表达式作为参数,这使得它可以按原样使用。