当我试图从从表中获取的XMLTYPE转换为nclob时,我得到了错误:
ORA-03001:未实现的特性
当我对动态创建的XMLTYPE进行同样的尝试时,一切都很好。
我的Oracle版本是:12.1.0.2.0。
代码示例:
这是正确的:
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
;这会产生错误:
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的转换,这种转换是可行的。
顺便说一句,为什么我不能和其他人一起抓住这个例外呢?
发布于 2018-06-22 14:06:57
我认为这与表存储使用SecureFile存储器有关,它不支持NCLOB,也不与NCLOB交互。作为查询的一部分创建的XMLType不使用SecureFile (或任何)存储,因此不会受到影响。
编译器似乎注意到您将使用SecureFile--存储的值--这可能导致了XMLType的不同风格(我还没有看到这个文档,但似乎您通常不需要担心不同的内部类型,比如日期;尽管dump()说它们都是58类型)。
它为什么抱怨使用从中提取的CLOB值是个谜;也许编译器正在重写代码,这意味着它认为XMLType被更直接地使用了。或者更有可能是CLOB的一种稍微不同的味道。(根据@BobJarvis的观察,我认为这似乎是可能的。)
这是编译器在试图操作PL/SQL变量时抛出错误--这是编译时错误,而不是运行时异常,这就是为什么不能捕获它的原因。
您可以通过将CLOB转换回XMLType (可能是另一个变体?)来解决这个问题。然后回到CLOB (不同的变体?)再一次:
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.为什么这样做,为什么它是必要的,这也是一个谜;但它暗示不同的数据类型的味道是有某种原因的,或者至少我是这样理解它的。
对于您的真实场景,它也可能不实用。您也可以将其作为查询的一部分:
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)。
发布于 2018-06-22 14:08:59
就而言,正在做什么:
当写入XMLTYPE列的数据被读入并转换为CLOB时,两个行结束序列(LF/LF)被添加到末尾。通过在v_clob := v_xml.getClobVal();之后添加以下内容,尝试在CLOB转换后打印出CLOB
DBMS_OUTPUT.PUT_LINE('DBMS_OUTPUT.PUT_LINE('v_clob=' || v_clob);在从数据库中获取的从XMLTYPE转换而来的CLOB数据上运行上述操作时
<a>test</a>后面有两条线提要。在从内联XMLTYPE转换而来的CLOB上运行DBMS_OUTPUT.PUT_LINE时,您将得到
<a>test</a>之后就没有线源了。
现在,事情是这样的--如果您尝试将CLOB从数据库中的XMLTYPE 转换为TRIM函数,则会得到ORA-03001: unimplemented feature。如果您将从内联XMLTYPE转换为TRIM函数的CLOB传递给它,它可以正常工作。因此,这个问题与TO_NCLOB无关--当您尝试使用从数据库中的XMLTYPE值转换的CLOB时,似乎就会发生这种情况。我不知道怎么解决或者解决这个问题。
至于在WHEN OTHERS中捕获-30001异常,我只需11.2g就可以了。
祝你好运。
https://stackoverflow.com/questions/50989082
复制相似问题