e-learning、オラクル研修、LMS(学習管理システム)のiStudy

e-learning、オラクル研修、LMS(学習管理システム)のiStudy

第103回「WEBアプリ作成(1) (Oracle DBとPL/SQLだけで、即、WEBアプリ)」

2014.08.21

こんにちは。インストラクターの蓑島です。
さすがに暑い夏ですね。体調を崩さぬように気を付けましょう。

今回からしばらくの間、今までに学習したPL/SQLを使って簡単なWEBアプリを作る方法をシリーズで解説したいと思います。

通常、WEBアプリケーションはいくつもの技術を組み合わせて作ります。
例えば、WEBサーバーやアプリケーションサーバー(WEBコンテナー、EJBコンテナー)があります。プロシージャ言語としては、PHPや、Perlや、Java、などが使われます。それらの言語で、WEBページ(HTMLドキュメント)を動的に生成するわけです。
また、データベースにアクセスするためには、それらの言語とデータベースの組み合わせに応じたコネクターやドライバーが必要です。
このように、普通はWEBアプリを作成するということはいくつもの技術を組み合わせる必要があります。

ところが、オラクルデータベースの場合は、オラクルデータベースだけで、WEBアプリが作成できます。他に必要なものはありません。もちろんWEBページを動的に生成する言語が必要ですが、それはPL/SQLです。
PL/SQLはオラクルデータベースに必ず組み込まれている言語なので、結局、オラクルデータベースさえあればWEBアプリが作成できます。おそらくこの方法が最も簡単なWEBアプリの作成方法だと思います。

ではその方法をご紹介します。それはオラクルデータベース上で3つのものを準備するだけです。

1. Oracel XML DB HTTP リスナー
2. DAD(Data Access Descriptor)
3. WEBページを生成するPL/SQLプロシージャ(通常はパッケージ化したもの)

上記の1と2が環境の準備であり、一度だけ設定するものです。

なお、私が今回のWEBアプリ作成シリーズのため用意したデータベースは、無償版の「Oracle Database 11g Express Edition」(OS Windows 7)です。
使用する機能は基本機能だけですから、おそろく10gバージョン以降であれば、どのバージョンでも動作可能と思います。
しかし、本番のデータベースでOracle XML DBなどの機能を使用している場合、何か影響があったら困りますので、必ずテスト環境で確認してください。

では早速、上記3つを解説します。

●1. Oracel XML DB HTTP リスナー
これは、WEBサーバーに相当する機能です。
HTTPリスナーとはいっても新規でリスナーを作成する必要はありません。すでに存在するデフォルトのリスナーに、Oracle XML DB のHTTPポートが登録されていればよいのです。HTTPポートを構成すればデフォルトリスナーには自動的に登録されます。例えば、HTTPポートが構成されてるかどうか、次の問い合わせで確認できます。

1
2
3
4
5
SELECT DBMS_XDB.GETHTTPPORT FROM DUAL;
 
GETHTTPPORT
-----------
        8080

私の場合、ポート番号8080で構成済みであることがわかります。

もしも、構成されていなければ、この問い合わせは、0(またはNULL)が返ります。
構成されていない場合、構成する必要があります。以下のようにします。

SQL> SHOW USER
ユーザーは"SYS"です。

1
2
3
SQL> EXEC  DBMS_XDB.SETHTTPPORT(8080);    -- HTTPポートの構成
 
PL/SQLプロシージャが正常に完了しました。

これでHTTPのポート番号が8080に構成されました。
HTTPのポート番号を変更したい場合も同じ方法です。HTTPのポート番号を無効にしたい場合は 0 に設定してください。

HTTPのポート番号を設定すると、デフォルトのリスナーに対して自動的にポート番号が登録されます。それはリスナーのステータスを参照すれば確認できます。パス(ORACLE_HOME/bin)の通っているOSのコマンドラインから以下のコマンドで確認します。

OS> lsnrctl status

そこで表示される情報に以下のような内容があればOKです。

(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=ホスト名)(PORT=8080))(Presentation=HTTP)

このような表示がされていれば、Oracel XML DB HTTP リスナーが準備されたことになります。

(参考)
Oracel XML DBは、通常、オラクルデータベースに組み込み済みです。しかしデータベースの作成のされ方によっては、XML DBが構成されていない場合もありえます。 その場合は、XML DBを後でインストールすることも可能です。
また、WEBサーバの役割としてXML DB HTTPリスナーを使うのではなく、Oracle Http Serverを使う方法もあります。その場合、Oracle Http Serverはデータベースサーバーとは別サーバーですので、間にファイアウォールを配置してセキュリティを高めるといった使い方もできます。
しかし、本メルマガでは極力簡単な方法を解説しますので、Oracel XML DBを使用する方法で解説します。

●2. DAD(Data Access Descriptor)
DADとは、ブラウザからリクエストするときのURLの中に記述するディレクトリのような記述の部分です。データベースアクセスに必要な属性をまとめたもので、作り方も大変簡単です。
早速、以下に、「DAD」というわかりやすい名前のDADを作成しましょう。
(なお、Oracle Http Severを使う場合はDADの作成方法は全く違います)

SQL> SHOW USER
ユーザーは"SYS"です。

1
2
3
EXEC DBMS_EPG.CREATE_DAD( 'DAD' , '/dad/*' );
 
PL/SQLプロシージャが正常に完了しました。

これで、「DAD」という名前のDADが作成されました。
これでURLの中で、/dad/~ という記述があれば、それは「DAD」という名前のDADを示すことになります。

もしも、DADを削除したければ以下のコマンドで可能です。
DBMS_EPG.DROP_DAD('DAD名');

なお、現在存在するDADの一覧を確認したい場合は以下のようなPL/SQLブロックで表示可能です。

SQL> SET SERVEROUTPUT ON -- 画面出力を有効

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
DECLARE
    V_LIST   DBMS_EPG.VARCHAR2_TABLE;   -- VARCHAR2型の配列です
BEGIN
    DBMS_EPG.GET_DAD_LIST(V_LIST);      -- その配列変数にDADの一覧を取得します
    FOR I IN  V_LIST. FIRST ..V_LIST. LAST  LOOP
        DBMS_OUTPUT.PUT_LINE(V_LIST(I));      -- 1件1件、表示します
    END LOOP;
END ;
/
 
--以下がDADの一覧
APEX
DAD
 
PL/SQLプロシージャが正常に完了しました。

私の場合、ご覧のように、「APEX」と、「DAD」という二つのDADがあります。
また、DADには属性があるのですが、以下のようなPL/SQLブロックで表示可能です。

SQL> SET SERVEROUTPUT ON

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
DECLARE
    V_NAMES   DBMS_EPG.VARCHAR2_TABLE;
    V_ATTRS   DBMS_EPG.VARCHAR2_TABLE;
BEGIN
     DBMS_EPG.GET_ALL_DAD_ATTRIBUTES( '&DAD_NAME' , V_NAMES, V_ATTRS);  
     IF  V_NAMES. COUNT = 0 THEN
         DBMS_OUTPUT.PUT_LINE( '属性なし' );
     ELSE
        FOR I IN V_NAMES. FIRST ..V_NAMES. LAST  LOOP
            DBMS_OUTPUT.PUT_LINE(V_NAMES(I) || ' -> ' || V_ATTRS(I));
        END LOOP;
     END IF;
END ;
/
 
dad_nameに値を入力してください: APEX
旧   5:     DBMS_EPG.GET_ALL_DAD_ATTRIBUTES( '&DAD_NAME' , V_NAMES, V_ATTRS);
新   5:     DBMS_EPG.GET_ALL_DAD_ATTRIBUTES( 'APEX' , V_NAMES, V_ATTRS);
 
-- 以下が「APEX」DADの属性の一覧です
database -username -> ANONYMOUS
default -page -> apex
document- table - name -> wwv_flow_file_objects$
document-path -> docs
document- procedure -> wwv_flow_file_mgr.process_download
nls-language -> american_america.al32utf8
request-validation- function -> wwv_flow_epg_include_modules.authorize
 
PL/SQLプロシージャが正常に完了しました。

上記の例は、1~13行目がPL/SQLブロックであり、5行目で&DAD_NAMEという置換変数があるので、実行前にキーボードから「APEX」というDAD名を入力しました(16行目)。そして、21~27行目が出力された属性の一覧です。

ご覧のように、「APEX」というDADには7個の属性があります。
では、今、作成したばかりの「DAD」という名前のDADはどうでしょうか?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
DECLARE
    V_NAMES   DBMS_EPG.VARCHAR2_TABLE;
    V_ATTRS   DBMS_EPG.VARCHAR2_TABLE;
BEGIN
     DBMS_EPG.GET_ALL_DAD_ATTRIBUTES( '&DAD_NAME' , V_NAMES, V_ATTRS);
     IF  V_NAMES. COUNT = 0 THEN
         DBMS_OUTPUT.PUT_LINE( '属性なし' );
     ELSE
        FOR I IN V_NAMES. FIRST ..V_NAMES. LAST  LOOP
            DBMS_OUTPUT.PUT_LINE(V_NAMES(I) || ' -> ' || V_ATTRS(I));
        END LOOP;
     END IF;
END ;
/
 
dad_nameに値を入力してください: DAD
旧   5:     DBMS_EPG.GET_ALL_DAD_ATTRIBUTES( '&DAD_NAME' , V_NAMES, V_ATTRS);
新   5:     DBMS_EPG.GET_ALL_DAD_ATTRIBUTES( 'DAD' , V_NAMES, V_ATTRS);
属性なし
 
PL/SQLプロシージャが正常に完了しました。

ご覧のように、今作成したばかりの「DAD」には属性はありませんが心配いりません。最低限、DADは存在するだけで十分機能します。
属性については必要があれば設定しますが、それは別の機会に解説します。

●3. WEBページを生成するPL/SQLプロシージャ(通常はパッケージ化したもの)
最後に、WEBページを生成するPL/SQLプロシージャです。まずは以下の例をご覧ください。

SQL> CONNECT SCOTT/password -- 一般ユーザで接続して

1
2
3
4
5
6
7
8
CREATE OR REPLACE PROCEDURE SAMPLE01(P1 IN VARCHAR2)
IS
BEGIN
  HTP.P( '指定されたパラメータは' || P1 || 'です。' );
END ;
/
 
プロシージャが作成されました。

ここではSCOTTという名前の一般ユーザで接続し、SAMPLE01という名前のプロシージャを作成しました。
このプロシージャで注目していただきたいのは、4行目の「HTP.P(~)」という記述です。
これはHTPパッケージのPというプロシージャなのですが、ここに指定した文字列ががそのままHTMLドキュメントへの出力になります。これは「PL/SQL Web Toolkit」というパッケージ群の一部の機能です。たくさんのパッケージがありますが、とりあえず、HTP.P さえ覚えていれば汎用的に対応できます。
また、このプロシージャには、P1というVARCHAR2型(文字型)のパラメータを設けました(1行目、4行目)。
このパラメータを受け渡すのに一番簡単な方法は、URLの最後に「?パラメータ名=値」という記述を追加する方法です。

とりあえず、ブラウザのURLに以下のように入力します。
データベースサーバーと同一のマシンであればホスト名はlocalhostです。

http://localhost:8080/dad/SAMPLE01?P1=ABC

つまり、http://dbのホスト名:ポート番号/dad/プロシージャ名?パラメータ名=値 という構文です。
そうすると、DADに何の属性もないので認証を求められます。以下の画面です。

認証

ここではこのプロシージャの所有者である、SCOTTユーザ名とそのパスワードを入力します。
そうすると以下のようなブラウザの表示となります。わかりやすく赤でコメントを入れました。

ブラウザ

つまりパラメータで指定したABCをインプットにして、SAMPLE01プロシージャが「指定されたパラメータはABCです」というアウトプットを生成したわけです。
とても簡単ですが、INPUTとOUTPUTのある、立派なWEBアプリケーションですね。
言語がPL/SQLですから、データベースのアクセスが簡単ですし、そのPL/SQL言語から直接HTMLに出力できるということは大変便利です。

ちょっと詳しい人ならここまでの情報をヒントに、後はいくらでも詳細なWEBアプリを作りこみできると思います。
なお今回は、作成したプロシージャはパッケージ化していないただのプロシージャで作成しました。しかし実際には、共通機能をファンクション化したり、リクエストの種類ごとにプロシージャを用意したりするのでサブプログラムの数が多くなります。よって、関連するプロシージャ、ファンクションはパッケージにまとめておくのが普通です。そうすると、URLでは「パッケージ名.プロシージャ名」のように記述するわけです。

次回以降は、こうしたPL/SQLを使ったWEBアプリの作成で定石的なパターンを解説していきます。
HTMLのタグについての若干の知識が必要となりますが、それほど難しいものではないです。
都度説明しながら進めていきます。ご期待ください!

先頭へ戻る