首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ORA-03001:将XMLTYPE从表转换为NCLOB时未实现的特性

ORA-03001:将XMLTYPE从表转换为NCLOB时未实现的特性
EN

Stack Overflow用户
提问于 2018-06-22 13:30:00
回答 2查看 2.3K关注 0票数 3

当我试图从从表中获取的XMLTYPE转换为nclob时,我得到了错误:

ORA-03001:未实现的特性

当我对动态创建的XMLTYPE进行同样的尝试时,一切都很好。

我的Oracle版本是:12.1.0.2.0

代码示例:

这是正确的:

代码语言:javascript
复制
DECLARE
    v_xml XMLTYPE;
    v_clob  CLOB;
    v_nclob nCLOB;
BEGIN
    SELECT XMLTYPE('<a>test</a>') INTO v_xml FROM dual;
    v_clob := v_xml.getClobVal();
    v_nclob := to_nclob(v_clob);
END
;

这会产生错误:

代码语言:javascript
复制
CREATE TABLE TEST_XMLTYPE_TO_NCLOB
(
      XML_MSG SYS.XMLTYPE
)
;
INSERT INTO TEST_XMLTYPE_TO_NCLOB (XML_MSG) VALUES (XMLTYPE('<a>test</a>'))
;
SET SERVEROUTPUT ON;
DECLARE
    v_xml       XMLTYPE;
    v_clob  CLOB;
    v_nclob nCLOB;
BEGIN
    SELECT XML_MSG INTO v_xml FROM TEST_XMLTYPE_TO_NCLOB WHERE rownum = 1;
    v_clob := v_xml.getClobVal();
    v_nclob := to_nclob(v_clob);
END
;

我想知道这是我的错误还是甲骨文的错误?

以及如何对从表获取的数据进行从XMLTYPE到NCLOB的转换,这种转换是可行的。

顺便说一句,为什么我不能和其他人一起抓住这个例外呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-06-22 14:06:57

我认为这与表存储使用SecureFile存储器有关,它不支持NCLOB,也不与NCLOB交互。作为查询的一部分创建的XMLType不使用SecureFile (或任何)存储,因此不会受到影响。

编译器似乎注意到您将使用SecureFile--存储的值--这可能导致了XMLType的不同风格(我还没有看到这个文档,但似乎您通常不需要担心不同的内部类型,比如日期;尽管dump()说它们都是58类型)。

它为什么抱怨使用从中提取的CLOB值是个谜;也许编译器正在重写代码,这意味着它认为XMLType被更直接地使用了。或者更有可能是CLOB的一种稍微不同的味道。(根据@BobJarvis的观察,我认为这似乎是可能的。)

这是编译器在试图操作PL/SQL变量时抛出错误--这是编译时错误,而不是运行时异常,这就是为什么不能捕获它的原因。

您可以通过将CLOB转换回XMLType (可能是另一个变体?)来解决这个问题。然后回到CLOB (不同的变体?)再一次:

代码语言:javascript
复制
DECLARE
    v_xml XMLTYPE;
    v_clob  CLOB;
    v_nclob nCLOB;
BEGIN
    SELECT XML_MSG INTO v_xml FROM TEST_XMLTYPE_TO_NCLOB WHERE rownum = 1;
    v_clob := v_xml.getClobVal();
    v_xml := xmltype(v_xml.getClobVal());
    v_clob := v_xml.getClobVal();
    v_nclob := to_nclob(replace(v_clob, chr(10), null));
END
;
/

PL/SQL procedure successfully completed.

为什么这样做,为什么它是必要的,这也是一个谜;但它暗示不同的数据类型的味道是有某种原因的,或者至少我是这样理解它的。

对于您的真实场景,它也可能不实用。您也可以将其作为查询的一部分:

代码语言:javascript
复制
DECLARE
    v_xml XMLTYPE;
    v_clob  CLOB;
    v_nclob nCLOB;
BEGIN
    SELECT XMLTYPE(t.XML_MSG.getClobVal()) INTO v_xml
    FROM TEST_XMLTYPE_TO_NCLOB t WHERE rownum = 1;
    v_clob := v_xml.getClobVal();
    v_nclob := to_nclob(replace(v_clob, chr(10), null));
END
;
/

PL/SQL procedure successfully completed.

这并不是更好的,但你也许可以隐藏更多。或者您也可以通过显式地使XMLType存储CLOB或二进制来避免这种情况,但这也可能不是一个选项或理想选择。

这可能会在Oracle支持下引发服务请求。这可能是一个已知的错误,但它可能会被视为预期的行为(也请参阅稍微相关的文档ID 1546992.1)。

票数 2
EN

Stack Overflow用户

发布于 2018-06-22 14:08:59

而言,正在做什么:

当写入XMLTYPE列的数据被读入并转换为CLOB时,两个行结束序列(LF/LF)被添加到末尾。通过在v_clob := v_xml.getClobVal();之后添加以下内容,尝试在CLOB转换后打印出CLOB

代码语言:javascript
复制
DBMS_OUTPUT.PUT_LINE('DBMS_OUTPUT.PUT_LINE('v_clob=' || v_clob);

在从数据库中获取的从XMLTYPE转换而来的CLOB数据上运行上述操作时

代码语言:javascript
复制
<a>test</a>

后面有两条线提要。在从内联XMLTYPE转换而来的CLOB上运行DBMS_OUTPUT.PUT_LINE时,您将得到

代码语言:javascript
复制
<a>test</a>

之后就没有线源了。

现在,事情是这样的--如果您尝试将CLOB从数据库中的XMLTYPE 转换为TRIM函数,则会得到ORA-03001: unimplemented feature。如果您将从内联XMLTYPE转换为TRIM函数的CLOB传递给它,它可以正常工作。因此,这个问题与TO_NCLOB无关--当您尝试使用从数据库中的XMLTYPE值转换的CLOB时,似乎就会发生这种情况。我不知道怎么解决或者解决这个问题。

至于在WHEN OTHERS中捕获-30001异常,我只需11.2g就可以了。

祝你好运。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50989082

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档