如何从Oracle中的文本返回子字符串

时间:2017-07-27 07:50:23

标签: sql oracle

我从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

2 个答案:

答案 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';