2017-07-27 20 views
0

Oracle DBのBLOB型の値をXML形式で取得しています。Oracleのテキストから部分文字列を返す方法

例えばそれに
<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は巨大であり、私は「部門」をconsits文字列を検索したいXMLは、非常に長いエンジニアリングの学位のIV年にI年度からすべての用語をカバーしています。今私は、私は以下のクエリ

SELECT Department/(SELECT Department FROM University where Department like '%Department %'), Term, Capacity From University 

をしようとしているが、クエリがエラー

を示している

 Department  Term  Capactity 
     Electronics I year  60 
     Computers  I year  65 
     Mechanical  I year  65 

下の形式にする必要がありますDBような結果から詳細を取得したいと思います

ORA-00932: inconsistent datatypes: expected NUMBER got CLOB 
+0

他の値にDepartment値を割り当てようとしています。 '/'記号を使って何をしたいですか? –

+0

「/」はfrom句 – Sawyer

+0

のサブクエリの構文です。「university」とは、XMLデータを既にリレーショナル形式に抽出したビューですか?あるいは、XMLを含むCLOBとして 'department'を持ち、用語と容量の列を別々にしたテーブルですか?どちらもかなり意味をなさない。質問にテーブルDDLを追加し、他の列のサンプルコンテンツを追加してください。 –

答えて

1

built-in XML DBはXMLから直接データを抽出します。

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などを取得します。他の2つの列はより簡単です。

含まれるCLOBをフィルタリングする必要がある場合は、fromの後に通常のようにwhere句を追加して、XMLTableへの結合を追加できます。

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'; 
+0

上記の選択句にwhere句を指定するには – Sawyer

+0

@Sawyer - 何をするのですか? 'XMLTable(...)x'の後に' where'節を追加することはできますが、抽出後に特定の部門や用語や容量の値をフィルタリングしたり、一部のCLOB値を制限したりします理由? –

+0

タイムスタンプcoloumnがあるので、2つのタイムスタンプの間でレコードを取得したいとします – Sawyer

1

あなたのSQLは間違っていると思います。 この/部門です。数字を使用する必要があります。 このサブクエリ (部門 '%Department%'のような部門からの選択科目) は文字列を返します。

次に動作しません。

あなたはXMLは、ここで検索に関するいくつかのドキュメント読むことができます:あなたが実際にあなたが使用することができ、あなたは(無効)の断片を示してきた、そのうちのXML文書を含むCLOBから開始する場合 https://docs.oracle.com/cd/B28359_01/appdev.111/b28369/xdb04cre.htm

+0

この文書は.xmlファイルからXMLを取ります。私がフェッチしている値はCLOBオブジェクトで、値は文字列 – Sawyer

+1

ですが、[link](https://docs.oracle.com/html/B14258_02/t_xml.htm)を使用してフェッチできますサブクエリを使用してより快適な方法でデータを取得します。 –

+0

+1リンクを与えるため。私は間違いなく答えとして上記を与えますが、私は読んで、解決策を見つけることによって医者にリセラーを行いました。時間がかかりますが、それ以外の方法はありません。 – Sawyer

関連する問題