从CLOB(包含XML)中提取特定值,同时为表的每一行创建一个分隔字符串。某些行上的CLOB值可能为null

时间:2013-02-28 15:27:25

标签: sql xml oracle clob xmltype

某些背景: 数据库是Oracle。我试图在表的每一行创建一个分隔的字符串。分隔字符串的某些值必须来自CLOB(包含XML)。某些行上的CLOB可能为空,这就是问题所在。

例如,我有一个表:'Item',其中包含以下行:'Item_ID','Item_CD','Item_TXT'(CLOB)。该表有两行。一行在'Item_TXT'中存储了以下XML,另一行'Item_TXT'为空。

<OuterTag>      
    <InnerTag>test</InnerTag>   
</OuterTag>     

我创建了以下SQL来返回分隔字符串的前3个元素:

SELECT 'Item%#'|| Item_ID ||'%#'|| Item_STAT_CD 
FROM Item; 

这项运作成功:

物品%#12345%#A

物品%#123456%#A

然后我尝试添加第4个元素(来自CLOB的值)。

SELECT 'Item%#'|| Item_ID ||'%#'|| Item_STAT_CD
EXTRACT(XMLTYPE(Item_TXT), '//OuterTag/InnerTag/text()').getStringVal()
FROM Item; 

此操作失败并出现以下错误:

ORA-06502: PL/SQL: numeric or value error
ORA-06512: at "SYS.XMLTYPE", line 272
ORA-06512: at line 1

我已将此问题缩小到有时Item_TXT为空且XMLTYPE()无法处理此问题。为了证明这一点,我运行了以下内容:

SELECT 'Item%#'|| Item_ID ||'%#'|| Item_STAT_CD
EXTRACT(XMLTYPE(Item_TXT), '//OuterTag/InnerTag/text()').getStringVal()
FROM Item
WHERE Item_TXT IS NOT NULL; 

这项运作成功:

物品%#12345%#A%#测试

有没有办法处理整个表,如果可用的话从clob中提取值,否则在分隔的字符串中添加null / nothing?

2 个答案:

答案 0 :(得分:7)

顺便提一下你的错误的原因是xmltype构造函数存在缺陷的空白。我个人总是使用xmltype.createxml(item_txt)代替。你会发现它也可以工作,而不必担心nvl等。

答案 1 :(得分:3)

尝试使用nvl

SELECT 'Item%#'|| Item_ID ||'%#'|| Item_STAT_CD ||'%#'|| 
EXTRACT(XMLTYPE(nvl(Item_TXT, '<OuterTag><InnerTag/></OuterTag>')), '//OuterTag/InnerTag/text()').getStringVal()
FROM Item;

Here is a sqlfiddle demo

或者您可以使用CASE声明:

SELECT 'Item%#'|| Item_ID ||'%#'|| Item_CD||'%#'||
case when Item_TXT is not null then
EXTRACT(XMLTYPE(Item_TXT), '//OuterTag/InnerTag/text()').getStringVal() end
FROM Item;