OracleでXMLを活用する
XSQLプログラミング入門

第2回 XSQLタグの機能を使う
(2/4ページ)

 

動的な検索も可能に

  今回、静的な引数しか渡してはいませんがこれらの引数を例えばskip-rows={@p_skip_rows} というように、変数を利用して動的に検索することによって、より高い汎用性を持たせることも可能です。実際、レコードが多い表の場合、何ページにも分けて出力することが多いですから、このような機能は非常に役にたちます。

 これら既存の引数のほかにも<xsql:query>ではデフォルト値を指定することもできます。例えば

デフォルト値を設定した検索

<?xml version='1.0' encoding="Shift_JIS"?>
<page xmlns:xsql="urn:oracle-xsql" connection="tkoyama">
  <xsql:query
      rowset-element="EMPLOYEES"
      row-element="EMPLOYEE"
      id-attribute="emp_id"
      id-attribute-column="EMPNO"
      p_deptno="30">
    SELECT * FROM EMP WHERE DEPTNO={@p_deptno}
  </xsql:query>
</page>

このXSQLファイルをp_depnoなしで呼び出したとき以下のようになります。

検索結果

<?xml version="1.0" encoding="Shift_JIS" ?>
<page xsql-timing="31">
  <employees>
    <employee emp_id="600">
    <empno>600</empno>
    <ename>佐藤聡俊</ename>
    <job>VP</job>
    <mgr>1</mgr>
    <hiredate>1995-04-01 00:00:00.0</hiredate>
    <sal>8000</sal>
    <deptno>30</deptno>
  </employee>
  <employee emp_id="50">
    <empno>50</empno>
    <ename>高橋敦子</ename>
    <job>Director</job>
    <mgr>600</mgr>
    <hiredate>1991-04-01 00:00:00.0</hiredate>
    <sal>6000</sal>
    <deptno>30</deptno>
  </employee>
  <employee emp_id="1001">
    <empno>1001</empno>
    <ename>本丸達也</ename>
    <job>Analyst</job>
    <mgr>50</mgr>
    <hiredate>1997-09-01 00:00:00.0</hiredate>
    <sal>3200</sal>
    <deptno>30</deptno>
  </employee>
  <employee emp_id="1201">
    <empno>1201</empno>
    <ename>砂金信一郎</ename>
    <job>Analyst</job>
    <mgr>50</mgr>
    <hiredate>1998-04-01 00:00:00.0</hiredate>
    <sal>3100</sal>
    <deptno>30</deptno>
  </employee>
  <employee emp_id="1401">
    <empno>1401</empno>
    <ename>小山尚彦</ename>
    <job>Analyst</job>
    <mgr>50</mgr>
    <hiredate>1999-09-01 00:00:00.0</hiredate>
    <sal>3000</sal>
    <deptno>30</deptno>
  </employee>
</employees>
</page>

 deptnoが30以外のひとである佐野力社長(depno=10)は摘出されませんでした。

該当レコードがないときに実行される文

 次に行く前に<xsql:no-rows-query>について簡単に説明しましょう。<xsql:no-rows-query>は<xsql:query>を親もしくは先祖として持ち、親<xsql:query>または親<xsql:no-rows-query>でレコードが見つからないときにのみ実行されます。例えば、以下のようなXSQLを"p_deptno=20"としてよびだしてみますと、はじめのSELECT文では該当レコードがありませんので、<xsql:no-rows-query>以下を実行することになります。

<xsql:no-rows-query>の例

<?xml version='1.0' encoding="Shift_JIS"?>
<page xmlns:xsql="urn:oracle-xsql" connection="tkoyama">
  <xsql:query
      rowset-element="EMPLOYEES"
      row-element="EMPLOYEE"
      id-attribute="emp_id"
      id-attribute-column="EMPNO">
    SELECT * FROM EMP WHERE DEPTNO={@p_deptno}
  <xsql:no-rows-query
      rowset-element="EMPLOYEES"
      row-element="EMPLOYEE"
      id-attribute="emp_id"
      id-attribute-column="EMPNO">
    SELECT * FROM EMP WHERE DEPTNO=30
    </xsql:no-rows-query>
  </xsql:query>
</page>

 このXSQLは先ほどの例の<xsql:query>タグ内でp_deptno="30"としたときとまったく同様の結果が得られます。

カーソルの扱い

 <xsql:ref-cursor-function>についてはPL/SQLでREF CURSORを返す関数を定義する必要があります。 たとえば、次のPL/SQLでREF CURSORを返す関数my_cursor.test_cursorを定義します。

カーソルを返す関数

CREATE OR REPLACE PACKAGE test_cursor AS
    TYPE any_cur IS REF CURSOR;
  FUNCTION test_cursor_query (table_id NUMBER)
      RETURN any_cur; END;
/
CREATE or REPLACE PACKAGE BODY test_cursor AS
    FUNCTION test_cursor_query (table_id NUMBER) RETURN any_cur
  IS
  rc1 any_cur;
  BEGIN
    IF table_id = 1 THEN
        OPEN rc1 FOR SELECT * FROM emp;
    ELSIF table_id = 2 THEN
      OPEN rc1 FOR SELECT * FROM dept;
    END IF;
    RETURN rc1;
  END;
END;
/
show err;
commit;

この関数を<xsql:ref-cursor-function>を使用して呼び出します。

XSQLから上記を呼び出す

<?xml version='1.0'?>
<xsql:ref-cursor-function
    connection="tkoyama"
    xmlns:xsql="urn:oracle-xsql">
  test_cursor.test_cursor_query({@p_number});
</xsql:ref-cursor-function>

するとp_number=1とした場合最初のXML文書と同じ出力を、p_number=2の場合は部署のXML文書を出力します。

部署の一覧を出力したXML文書

<?xml version="1.0" ?>
<ROWSET>
  <ROW num="1">
    <DEPTNO>10</DEPTNO>
    <DNAME>社長室</DNAME>
    <LOC>GC18F</LOC>
  </ROW>
  <ROW num="2">
    <DEPTNO>20</DEPTNO>
    <DNAME>営業部</DNAME>
    <LOC>GC12F</LOC>
  </ROW>
  <ROW num="3">
    <DEPTNO>30</DEPTNO>
    <DNAME>e-business</DNAME>
    <LOC>GC14F</LOC>
  </ROW>
  <ROW num="4">
    <DEPTNO>40</DEPTNO>
    <DNAME>教育本部</DNAME>
    <LOC>用賀</LOC>
  </ROW>
</ROWSET>

というようになります。 ご覧のように、このタグを使用することでかなり応用のき
いた出力をすることが可能です。 また、<xsql:ref-cursor-function>は
<xsql:query>と同じattributeを使用することができます。

オブジェクトデータの取り扱い

 オブジェクトとして定義されたデータが、SELECT文によりネストされて表示される点について紹介しましょう。XSQLリリースノートで使われている例が分かりやすいかとおもいますのでここで再現します。

データを追加する

CREATE TYPE POINT AS OBJECT (
X NUMBER, Y NUMBER
);
CREATE TABLE LOCATION (
NAME VARCHAR2(80),
ORIGIN POINT
);
INSERT INTO LOCATION VALUES ('point1', POINT(0, 0));
INSERT INTO LOCATION VALUES ('point2, POINT(10, 5));
INSERT INTO LOCATION VALUES ('point3', POINT(5, 10));
COMMIT;

データの検索

<?xml version='1.0' encoding="Shift_JIS"?>
<page xmlns:xsql="urn:oracle-xsql" connection="tkoyama">
  <xsql:query
      rowset-element="LOCATIONS"
      row-element ="LOCATION">
    SELECT * FROM LOCATION
  </xsql:query>
</page>

検索結果

<?xml version="1.0" encoding="Shift_JIS" ?>
<page xsql-timing="4039">
  <LOCATIONS>
    <LOCATION num="1">
      <NAME>point1</NAME>
      <ORIGIN>
        <X>0</X>
        <Y>0</Y>
      </ORIGIN>
    </LOCATION>
    <LOCATION num="2">
      <NAME>point2</NAME>
      <ORIGIN>
        <X>10</X>
        <Y>5</Y>
      </ORIGIN>
    </LOCATION>
    <LOCATION num="3">
      <NAME>point3</NAME>
      <ORIGIN>
        <X>5</X>
        <Y>10</Y>
      </ORIGIN>
    </LOCATION>
  </LOCATIONS>
</page>

 ご覧のように、出力されたXML文書は<ORIGIN>のところでネストされています。


 目次 

 1ページ

 主要XSQLタグの概要
   XML形式への出力言語
 DataをDBから取り出すときに使用するXSQLタグ
   XSQLでデータベースを検索する
   引数を用いた動的な検索

 2ページ
   動的な検索も可能に
   該当レコードがないときに実行される文
   カーソルの扱い
   オブジェクトデータの取り扱い
   
 3ページ
 Dataを挿入または変更するときに使用するXSQLタグ
   INSERT文を実行する
   ストアドプロシージャを実行する
   Webフォームからデータ入力する(1)
   Webフォームからデータ入力する(2)

 4ページ
 他のXML文書やXSQL出力をインポートするタグ
 その他の便利なXSQLタグ
   HTTPパラメータを処理する
   パラメータの設定
   セッションの設定
   クッキーの設定
   スタイルシートに実行結果を渡す

「連載 XSQLプログラミング入門」

 



XML & SOA フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

HTML5+UX 記事ランキング

本日月間