我从Oracle DB中获取BLOB类型的值,并以XML的形式获取。 XML是巨大的,我想搜索其中包含“部门”的字符串,例如
<ElectronicsDepartment>
<term>I year</term>
<Capacity>60</Capacity>
</ElectronicsDepartment>
<ComputersDepartment>
<term>I year</term>
<Capacity>65</Capacity>
<ComputersDepartment>
<MechanicalDepartment>
<term>I year</term>
<Capacity>65</Capacity>
</MechanicalDepartment>
XML很长,涵盖了从I年到IV年的工程学位的所有术语。现在我想从数据库中获取详细信息,结果应采用以下格式
Department Term Capactity
Electronics I year 60
Computers I year 65
Mechanical I year 65
我一直在尝试以下查询
SELECT Department/(SELECT Department FROM University where Department like '%Department %' ), Term, Capacity From University
但查询显示错误
ORA-00932: inconsistent datatypes: expected NUMBER got CLOB
答案 0 :(得分:1)
我认为你的sql是错误的。 / 用于分区,然后需要与数字一起使用。 这个子查询 (SELECT部门FROM大学,部门喜欢'%Department%') 返回一个字符串。
然后它无法正常工作。
您可以阅读一些关于XML搜索herE的文档: https://docs.oracle.com/cd/B28359_01/appdev.111/b28369/xdb04cre.htm
答案 1 :(得分:1)
如果您实际上是从包含XML文档的CLOB开始的,您已经显示了一个(无效的)片段,那么您可以使用built-in XML DB函数直接从XML中提取数据。 / p>
您似乎希望匹配以Department
结尾的任何节点,并将该节点名称的第一部分提取为部门名称,以及其下的术语和容量值。
您可以使用XMLTable和合适的XPath,例如:
-- CTE to represent your raw XML CLOB, with dummy root node
with university (department) as (
select to_clob('<root>
<ElectronicsDepartment>
<term>I year</term>
<Capacity>60</Capacity>
</ElectronicsDepartment>
<ComputersDepartment>
<term>I year</term>
<Capacity>65</Capacity>
</ComputersDepartment>
<MechanicalDepartment>
<term>I year</term>
<Capacity>65</Capacity>
</MechanicalDepartment>
</root>') from dual
)
-- end of CTE, actual query below
select x.department, x.term, x.capacity
from university u
cross join xmltable (
'//*[ends-with(name(), "Department")]'
passing xmltype(u.department)
columns department varchar2(20) path 'substring(name(), 1, string-length(name()) - 10)',
term varchar2(10) path 'term',
capacity number path 'Capacity'
) x;
DEPARTMENT TERM CAPACITY
-------------------- ---------- ----------
Electronics I year 60
Computers I year 65
Mechanical I year 65
'//*[ends-with(name(), "Department")]'
仅匹配以Department
结尾的节点。 'substring(name(), 1, string-length(name()) - 10)'
从该节点名称中提取除最后10个字符之外的所有字符,获取Computers
或其他任何字符。另外两列更直接。
如果您需要过滤包含哪些CLOB,您可以在where
之后正常添加from
子句并加入XMLTable,例如过滤university
表中的时间戳列:
select x.department, x.term, x.capacity
from university u
cross join xmltable (
'//*[ends-with(name(), "Department")]'
passing xmltype(u.department)
columns department varchar2(20) path 'substring(name(), 1, string-length(name()) - 10)',
term varchar2(10) path 'term',
capacity number path 'Capacity'
) x
where your_timestamp_col >= timestamp '2017-06-01 00:00:00'
and your_timestamp_col < timestamp '2017-07-01 00:00:00';