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>のところでネストされています。