ページの先頭行へ戻る
Symfoware Server V10.0.0 アプリケーション開発ガイド(共通編)

12.2.1 SQL/XMLでXMLデータを検索する

SQL/XMLで、BLOB型の列に格納されたXMLデータを検索する場合には、XQueryを使用します。XQueryは、XMLQUERY関数またはXMLEXISTS述語に指定します。XMLQUERY関数またはXMLEXISTS述語を問合せ式に指定することで、表に格納されたXMLデータを検索することができます。

XQueryを使用してXMLデータを検索するときの権限は、XMLデータを格納している列が存在する表への参照権限と同じです。XMLデータが格納された表に対するSELECT権がこれに当たります。

XML構文解析

XML構文解析は、BLOB型の列に格納されたテキスト形式のXMLデータを階層形式に変換する処理です。この処理は、以下のような検索を実施するときに、暗黙的に行われ、データ形式に誤りがあれば、参照処理がエラーになります。

[XML構文解析を実施する検索]

  • XMLデータの一部分を取り出す検索

  • FLWOR式を指定した検索

  • 条件式を指定した検索

  • 量化式を指定した検索

参考

rdbunlxコマンドでサポートしているXQuery式は、XML構文解析を実施しません。詳細については、“XQueryリファレンス”の“rdbunlxコマンドのサポート一覧”を参照してください。

また、構文解析時にXMLデータの妥当性検証、内部実体の展開および外部実体の展開は行いません。

12.2.1.1 XMLQUERY関数

XMLQUERY関数は、SQLから、XQuery式を実行するための関数です。XMLQUERY関数は、XQueryの評価結果であるシーケンスの各項目を先頭から順に連結して返却します。このとき、シーケンスの各項目の間を区切る文字はありません。

注意

カンマ記号、空白文字、改行などでシーケンスの各項目が区切られることはありません。ただし、本マニュアルの例では、見易さを考慮して、シーケンスの各項目の間に改行を適宜含めて、XMLQUERY関数の評価結果を表現しています。

XMLQUERY関数でXQuery式を利用すると、格納されたXMLデータから条件に一致する一部分を取り出すことができます。

以降の説明では、従業員スキーマに定義された従業員表を例として使用します。従業員表は、以下のような構成になっています。

列名

列のデータ型

従業員番号

INTEGER

従業員情報

BLOB(20K)

従業員表には、以下の3件のデータが格納されているとします。

表12.2 従業員スキーマ.従業員表

従業員番号

従業員情報

54319

<従業員情報 従業員番号="54319">
<名前>佐藤  一郎</名前>
<所属 code="k0312" >第一開発部</所属>
<派遣先>東京都港区</派遣先>
<派遣先>東京都千代田区</派遣先>
<派遣先>神奈川県横浜市</派遣先>
<電話番号>050-1111-2222</電話番号>
</従業員情報>

54320

<従業員情報 従業員番号="54320">
<名前>田中  大輔</名前>
<所属 code="f0021" >第二開発部</所属>
<派遣先>神奈川県横浜市</派遣先>
<電話番号>030-2222-1111</電話番号>
</従業員情報>

54321

<従業員情報 従業員番号="54321">
<名前>山本  翔太</名前>
<所属 code="f0021" >第三開発部</所属>
<派遣先>東京都大田区</派遣先>
<派遣先>神奈川県横浜市</派遣先>
<電話番号>030-2222-2222</電話番号>
</従業員情報>

XMLQUERY関数の使用例

従業員表に対して、以下のような問合せを行ったとします。

SELECT 従業員番号, XMLQUERY('/従業員情報/派遣先' PASSING 従業員情報) FROM 従業員スキーマ.従業員表

問合せの結果、以下の3件のデータが返却されます。

従業員番号

従業員情報

54319

<派遣先>東京都港区</派遣先>
<派遣先>東京都千代田区</派遣先>
<派遣先>神奈川県横浜市</派遣先>

54320

<派遣先>神奈川県横浜市</派遣先>

54321

<派遣先>東京都大田区</派遣先>
<派遣先>神奈川県横浜市</派遣先>

この例は、XMLQUERY関数の一般的な使用方法を示しています。XMLQUERY関数が、検索対象となる表の各行に格納されたXMLデータ1つずつに適用されて、結果の各行が1つのXMLデータからの検索結果を表しています。

最初の行には、3つの<派遣先>要素のシーケンスが含まれているのに対して、2番目の行には1つの<派遣先>要素のシーケンスが含まれています。これは、1番目のXML 文書に3つの<派遣先>要素が含まれていて、XMLQUERY関数はXQuery式を満たすすべての要素のシーケンスを返却したためです。

注意

1件目と3件目に返却された結果にあるXMLデータは、ルート要素が複数存在するため、整形式ではありません。この結果を受け取るアプリケーションが、結果のデータを整形式のXMLデータとして利用したい場合は、以下のいずれかの対処を行ってください。

  • アプリケーションにおいて、整形式でない結果のデータを整形式となるように加工してください。

  • 結果が必ず整形式となるように、検索対象のXMLデータ、およびXQuery式を修正してください。

XMLQUERY関数がNULLを返却する場合

XQuery式が空のシーケンスを返却する場合、XMLQUERY関数の結果はNULL値になります。

従業員表に対して、以下のような問合せを行ったとします。

SELECT 従業員番号, XMLQUERY('/従業員情報/所属[text()="第二開発部"] ' PASSING 従業員情報) FROM 従業員スキーマ.従業員表

問合せの結果、以下の3件のデータが返却されます。

従業員番号

従業員情報

54319

NULL

54320

<所属 code="f0021" >第二開発部</所属>

54321

NULL

<所属>要素の値が“第二開発部”ではない行に対しては、NULL値が返却されます。2行目については、XQuery式を満たすので<所属>要素が返却されます。

空のシーケンスを含む行の返却を回避するには、WHERE句にXMLEXISTS述語を記述します。たとえば、前述の参照は、以下のようにフィルタを選択リストに指定したXMLQUERY関数ではなくWHERE句に記述することで、空のシーケンスを含む行の返却を回避できます。

SELECT 従業員番号, XMLQUERY('/従業員情報/所属' PASSING 従業員情報) FROM 従業員スキーマ.従業員表
WHERE XMLEXISTS('/従業員情報[所属/text()="第二開発部"]' PASSING 従業員情報)

問合せの結果、以下の1件のデータが返却されます。

従業員番号

従業員情報

54320

<所属 code="f0021" >第二開発部</所属>

XMLEXISTS述語についての詳細は、“12.2.1.2 XMLEXISTS述語”を参照してください。

12.2.1.2 XMLEXISTS述語

XMLEXISTS述語は、XQuery式が1つ以上の項目のシーケンスを返却するかどうかを評価します。この述語に指定されたXQuery式が空のシーケンスを返す場合、XMLEXISTS述語の結果は偽となります。その他の場合には、真となります。

一般に、XMLQUERY関数は、選択されたXMLデータの一部分を取り出すために選択リストの中で使用されます。XMLQUERY関数のXQuery式に指定された検索条件は、結果として取り出す行を限定するのではなく、XMLデータのどの一部分を取り出すかを決めるためだけに使用されます。

XMLデータの値に応じて結果として取り出す行を限定するには、問合せのWHERE句にXMLEXISTS述語を指定します。

たとえば、次の問合せは、XMLEXISTS述語を使用して、取り出す行を<所属>要素のcode属性の値が“f0021”であるXMLデータを含むものだけに限定する方法を示しています。

SQLは大小文字を区別しませんが、XQuery式は大小文字を区別することに注意してください。

SELECT 従業員情報
FROM 従業員スキーマ.従業員表
WHERE XMLEXISTS ('/従業員情報[所属/@code = "f0021" ]' PASSING 従業員情報)

注意

結果が正しく返却されるようにするために、XMLEXISTS述語のXQuery式が正しく指定されていることを確認してください。

従業員表から、従業員番号が54321のデータを取り出したい場合を例として説明します。

以下の2つの問合せは、XQuery式が少し異なるために、異なる結果を返します。

SELECT *
FROM 従業員スキーマ.従業員表
WHERE XMLEXISTS ('/従業員情報[@従業員番号=54321]' PASSING 従業員情報)
SELECT *
FROM 従業員スキーマ.従業員表
WHERE XMLEXISTS ('/従業員情報/@従業員番号=54321' PASSING 従業員情報)

1つめの問合せでは、XQuery式にパス式を指定しているため、従業員番号が54319、54320の行に対し、XQuery式は空のシーケンスを返します。
したがって、XMLEXISTS述語の結果は偽となり、それらの行が検索結果として取り出されることはなく、従業員番号が54321の行のみが返却されます。

2つめの問合せでは、XQuery式に比較式を指定しているため、従業員番号が54319、54320の行に対し、XQuery式は偽(空ではないシーケンス)を返します。
したがって、XMLEXISTS述語の結果は真となり、検索結果として、XQuery式が真(空ではないシーケンス)を返す、従業員番号が54321の行だけでなく、従業員番号が54319、54320の行も返却されます。このため、予期したとおりの結果を得ることができません。

12.2.1.3 XMLシリアライゼーション

XMLシリアライゼーションは、XML構文解析処理により階層形式に変換したXMLデータを、テキスト形式のXMLデータに変換する処理です。

Symfoware/RDBのXMLシリアライゼーションは、XMLデータ参照時に暗黙的に行われ、XQueryデータモデルの表現から、BLOB型に変換します。

注意

XMLシリアライゼーションの処理内容についての注意点を以下に示します。

  • XML宣言は、XMLデータに含まれません。

  • DTD宣言は、XMLデータに含まれません。

  • XMLデータ内のコメントは、そのまま再現されます。

  • 要素の内容の空白は削除します。

  • XMLシリアライゼーションを行うときに、対象のシーケンス中に属性要素が含まれている場合には、エラーになります。

12.2.1.4 SQL/XMLで扱えるデータ形式

SQL/XMLで扱えるデータ形式について説明します。

XMLデータの文字コード

SQL/XMLがサポートするXMLデータの文字コードを以下に示します。

XMLデータの形式について

SQL/XMLがサポートするXMLデータの形式について以下に記述します。

SQL/XMLは、XML標準である整形式の条件を満たすXMLデータをサポートします。

整形式の条件について記述します。

ポイント

要素とは、開始タグで始まり、終了タグで終わる単位です。

開始タグと終了タグの間に要素の内容があります。要素の内容が空である場合、空要素タグを記述することができます。

XMLデータの構成要素の記述例を以下に記述します。

<Company  Place =  "東京">  富士通    </Company>
開始タグ名  属性名  属性値   要素の内容   終了タグ名

空要素タグの記述例を以下に記述します。

<Company/>

QNameを構成するNCNameに記述可能な文字について以下に示します。

構成要素

記述可能な文字

NCName

  • 先頭に記述可能な文字

    • アンダースコア(“_”)

    • コロン(“:”)

    • Letterクラスの文字
      (アルファベット、ひらがな、カタカナ、漢字など)

  • 2文字目以降に記述可能な文字

    • 先頭に記述可能な文字

    • ピリオド(“.”)

    • ハイフン(“-”)

    • Digitクラスの文字(数字)

    • Combining Characterクラスの文字
      (アクセント記号など)

    • Extenderクラスの文字
      (他の文字の後や間に使用される文字)

要素の内容
属性値

キャラクタ(Character)範囲の文字

参照

QNameについては“XQueryリファレンス”を参照してください。

注意

属性値は、二重引用符(“ " ”)、もしくは、引用符(“ ' ”)で囲う必要があり、二重引用符で囲まれている属性値に二重引用符は指定できません。また、引用符で囲まれている属性値に、引用符は指定できません。

以下に正しいXML形式のXMLデータを記述します。

<受注伝票>
  <伝票番号>E001001</伝票番号>
  <契約日>2007-01-01</契約日>
  <納入日>2007-01-21</納入日>
  <受注先>
    <社名>ABC銀行</社名>
    <コード>B001</コード>
  </受注先>
  <商品>
    <商品名>FMVM47073</商品名>
    <個数>10個</個数>
  </商品>
</受注伝票>

参照

Letterクラスの文字、Digitクラスの文字、Combining Characterの文字、Extenderクラスの文字、および、キャラクタ(character)範囲の文字は、W3Cの勧告として公布されている XML1.0(http://www.w3.org/TR/xml)の内容を参照してください。