在 Oracle 中,如何从具有多个值的 XML/CLOB 字段中提取值?
In Oracle, how to extract values from XML/CLOB field that has multiple values?
我正在尝试使用 Oracle 函数 EXTRACTVALUE() 和 xmltype() 从 CLOB 数据类型中提取字段值。我的问题是因为某些行中有多个值,我不确定如何让 EXTRACTVALUE() 处理这些值。在下面的示例中,有两种情况——语法在第一行正确工作,但在第二行不正确(我收到一条解析失败消息,因为有多个 fields/values)。在存在多个值的情况下,我只想采用最新(最后)的一组值。
create table TEST1
(
id1 numeric(2),
col1 CLOB not null
);
-- Insert data:
INSERT INTO TEST1 (id1, col1) values (1, '<raceHistory><raceDate>1980-05-26</raceDate><raceType>CLASSIC</raceType></raceHistory>');
INSERT INTO TEST1 (id1, col1) values (2, '<raceHistory><raceDate>1997-06-21</raceDate><raceType>MARATHON</raceType></raceHistory><raceHistory><raceDate>2017-01-01</raceDate><raceType>SKATE</raceType></raceHistory>');
-- Make sure it populated correctly.
select * from TEST1;
-- Now try to extract the field values for raceDate and raceType:
-- The parsing works fine for the first row...
SELECT
EXTRACTVALUE(xmltype(col1), '/raceHistory/raceDate') as raceDate,
EXTRACTVALUE(xmltype(col1), '/raceHistory/raceType') as raceType
FROM TEST1
WHERE id1 = 1;
-- ... but the parsing fails on this one because there are multiple values:
SELECT
EXTRACTVALUE(xmltype(col1), '/raceHistory/raceDate') as raceDate,
EXTRACTVALUE(xmltype(col1), '/raceHistory/raceType') as raceType
FROM TEST1
WHERE id1 = 2;
我想要的输出是这样的——对于第二行,我只想要最后一个值(即最新的利率表变量)。
id1 raceDate raceType
1 1985-05-25 CLASSIC
2 2017-01-01 SKATE
好吧,一个问题是您的字符串无效 XML - 它们需要一个包含字符串其余部分的根节点。给根节点起什么名字并不重要。我不确定您使用的是哪个 Oracle 版本,但在 12c 中,如果没有根节点,xmltype()
将失败并显示 LPX-00245: extra data after end of document
。
就是说,您只需将 XPath 更改为例如/raceHistory[last()]/raceDate
获取最后一个 raceHistory 条目。
这是我向您的 xml 添加根节点的示例:
with test1 as (select 2 as id1, '<root><raceHistory><raceDate>1997-06-21</raceDate><raceType>MARATHON</raceType></raceHistory><raceHistory><raceDate>2017-01-01</raceDate><raceType>SKATE</raceType></raceHistory></root>' as col1 from dual)
SELECT
EXTRACTVALUE(xmltype(col1), '/root/raceHistory[last()]/raceDate') as raceDate,
EXTRACTVALUE(xmltype(col1), '/root/raceHistory[last()]/raceType') as raceType
FROM TEST1
WHERE id1 = 2;
请注意,这不会获取具有最新 raceDate 的 raceHistory 条目——那样会更复杂。它只是获取字符串中的最后一个 raceHistory 条目。在您的情况下,它们已经按照这种方式排序;我只是想澄清一下。
我正在尝试使用 Oracle 函数 EXTRACTVALUE() 和 xmltype() 从 CLOB 数据类型中提取字段值。我的问题是因为某些行中有多个值,我不确定如何让 EXTRACTVALUE() 处理这些值。在下面的示例中,有两种情况——语法在第一行正确工作,但在第二行不正确(我收到一条解析失败消息,因为有多个 fields/values)。在存在多个值的情况下,我只想采用最新(最后)的一组值。
create table TEST1
(
id1 numeric(2),
col1 CLOB not null
);
-- Insert data:
INSERT INTO TEST1 (id1, col1) values (1, '<raceHistory><raceDate>1980-05-26</raceDate><raceType>CLASSIC</raceType></raceHistory>');
INSERT INTO TEST1 (id1, col1) values (2, '<raceHistory><raceDate>1997-06-21</raceDate><raceType>MARATHON</raceType></raceHistory><raceHistory><raceDate>2017-01-01</raceDate><raceType>SKATE</raceType></raceHistory>');
-- Make sure it populated correctly.
select * from TEST1;
-- Now try to extract the field values for raceDate and raceType:
-- The parsing works fine for the first row...
SELECT
EXTRACTVALUE(xmltype(col1), '/raceHistory/raceDate') as raceDate,
EXTRACTVALUE(xmltype(col1), '/raceHistory/raceType') as raceType
FROM TEST1
WHERE id1 = 1;
-- ... but the parsing fails on this one because there are multiple values:
SELECT
EXTRACTVALUE(xmltype(col1), '/raceHistory/raceDate') as raceDate,
EXTRACTVALUE(xmltype(col1), '/raceHistory/raceType') as raceType
FROM TEST1
WHERE id1 = 2;
我想要的输出是这样的——对于第二行,我只想要最后一个值(即最新的利率表变量)。
id1 raceDate raceType
1 1985-05-25 CLASSIC
2 2017-01-01 SKATE
好吧,一个问题是您的字符串无效 XML - 它们需要一个包含字符串其余部分的根节点。给根节点起什么名字并不重要。我不确定您使用的是哪个 Oracle 版本,但在 12c 中,如果没有根节点,xmltype()
将失败并显示 LPX-00245: extra data after end of document
。
就是说,您只需将 XPath 更改为例如/raceHistory[last()]/raceDate
获取最后一个 raceHistory 条目。
这是我向您的 xml 添加根节点的示例:
with test1 as (select 2 as id1, '<root><raceHistory><raceDate>1997-06-21</raceDate><raceType>MARATHON</raceType></raceHistory><raceHistory><raceDate>2017-01-01</raceDate><raceType>SKATE</raceType></raceHistory></root>' as col1 from dual)
SELECT
EXTRACTVALUE(xmltype(col1), '/root/raceHistory[last()]/raceDate') as raceDate,
EXTRACTVALUE(xmltype(col1), '/root/raceHistory[last()]/raceType') as raceType
FROM TEST1
WHERE id1 = 2;
请注意,这不会获取具有最新 raceDate 的 raceHistory 条目——那样会更复杂。它只是获取字符串中的最后一个 raceHistory 条目。在您的情况下,它们已经按照这种方式排序;我只是想澄清一下。