Active Server Pages

with ActiveX Data Object & Advanced Database Connectorによる

Webデータベース
プログラミング

秋月巌 AKIZUKI, Iwao
BackOffice(TM)Magazine責任編集者



●ダウンロードモジュール

 前々号のVisual Basicマガジン誌において,ダウンロード可能なMicrosoft Visual InterDevを紹介した.付録のCD-ROMにも同じモジュールがコピーされていたが,インストーラに問題があり,多くのユーザーから,セットアップに失敗したという報告をうけた.私自身,インストールに成功したのは,Windows NT ServerがNTFS形式でセットアップされているマシン一台だけだった.
 興味深いプロダクトがWebのサイトにアップロードされるたびに,ダウンロードして何とか動作させようとするのだが,その成功率は日増しに低下している.私のテスティング経験からしても,インストーラの障害を取り除くことは難しい.さまざまなプログラムが,それぞれのディレクトリやレジストリに記録されている環境に,うまく自分のプロダクトを紛れ込ませるのは,それほど簡単なことではない.ましてやベータ版のための暫定的なインストーラのために多くのコストも時間も費やすことはできない.


★Powersoft Jato

 最近,苦労したのはPowersoft社がサイトで公開しているJAVAベースのRAD環境“Jato”の調査をしているときである.この記事はWebでデータベースプログラムを作成しようという人が読むだろうから,Jatoという名前は覚えておいていい.Optima++というC++のRADツールと同じ環境で動作するJatoは,ネイティブでJDBCコネクタを備えている.Powersoftの製品は膨大なバグを含むPower Builder4.0以来,私はあまり信用していないのだが,同プロダクトが持つData Windowの機能はクライアント/サーバーシステムの開発者にはあまりにも魅力的である.そしてOptima++のC++バージョンにはActiveXコントロールとして,このData Windowが装備されている.だから,JDBCサポートのJatoが同等の機能を備えていてもおかしくないだろう,と考えたのである.


★JDBC接続を断念

 結果からいえば,ダウンロード可能なモジュールにData Windowは含まれていなかったのだが,もし,JDBCベースでこの機能がサポートされれば,Webデータベースシステムは画期的な進歩を始めることになる.とにかく,私はこの新しいシステムをかなりの期待をもって(まもなく発表されるであろうBorland Open J Builderを頭に思い浮かべながら),自分のマシンにインストールした.プロジェクトをロードしただけで,開発環境が消えてしまう現象は,私に悪夢のPower Builder4.0を思い起こさせた.また,データベースの接続をするために,さらに何時間かをかけてSQL Anywhereの最新バージョンもダウンロードした.このセットアップは無事に終了した.日本語版のトライアル版にあったODBCの障害もクリアされており,十分な期待を抱かせた.しかし,私はJatoをデータベースに接続することができなかった.問題だったのは接続ではなく,それ以前にプログラムをまともに実行することができなかったのである.


★移り気なデベロッパー

 Jatoは,RADツールとしてMicrosoft Visulal J++よりはるかに先行しており,この分野で圧倒的なリードを示すSymantec Visual Cafeとくらべても,いくつかの部分で優れている.私はJatoとOptima++の組み合わせを,次期主力開発ツールの候補に考えていたのだが,今はやはりBorland C++ BuilderとOpen J Builderの組み合わせにするべきかという考えに傾いている.
 開発者の心理は移ろいやすい.Open J Builderのように待たせているばかりでは,心変わりをされる可能性があるし,だからといって未完成の製品を公開すれば,心は離れていく.


●Active Server PagesとVisual InterDev

 閑話休題.Active Server Pagesの日本語プレビュー版が,現在Microsoftのサイトからダウンロードできる.この記事が出るころには正式版が発表されているはずである.また,間もなくActive Server Pagesの開発環境であるVisual InterDevも発売される.Visual InterDevに同梱のActive Server Pagesと,単体のActive Server Pages(無償)とが同じものなのかどうかは,尋ねる人によって違う答えが返ってくる.私の勘では,これらは同じもののような気がするが,多少のスペックの差はあるのかもしれない.


★簡単なインストール

 Active Server Pagesはいくつかの環境上で動作するが,私はWindowsNT4.0 Serverでしか,確認をしていない.
 とにかく,このプロダクトのインストールは簡単に終了する.今までにいくつかのマシンにインストールをしたが,失敗したことはない.インストールしてリブートするだけで,IISのWebパブリッシングサービスは見事にアクティブサーバーに変貌している.しかも,以前のInterDevのベータに付属していたものにあった2バイト文字の扱いの障害が克服されている.私はすでに実稼動するシステムをこのプロダクトを利用して作成したが,今までにバグが理由で開発が遅延したことはない.もちろん,それはActive Server Pagesにバグがないことを示すものではない.しかし,最近の開発ツールにはめずらしく,信用に足るものだということはいえると思う.しかも,使用したのは,プレビュー版なのである.


★プログラミングツール

 もっとも,プログラムの開発にはVisual InterDevは使用していない.キーワードの色分け表示等の利点はあるにしても,ベータ版の不安定さからくるデメリットが,メリットを上回っていたからである.結局,すべてのプログラムをテキストエディタでコーディングすることになる.この作業は職人芸を要求されるが,IDCやOLEISAPIのプログラミングに比べれば,はるかに人間的な作業である.私の家内はVisual Basicプログラマだが,IDCでプログラムを書かせると嫌な顔をしていたのに,Visual Basic ScriptでActive Server Pageプログラムを喜んで作っている.
 もし,製品版のVisual InterDevが手に入るならば,これを利用した方がいいだろう.必須とまではいわないが,あれば便利なツールである.特にデザインタイムActiveXコントロールが生成するコードは,少なくとも学習の役には立つ.もっとも,このコードはエラーハンドリングもしっかりとしており,よく書けているが,かなり冗長性があり,学習に適しているわけではない.


●Active Server Pagesとは?

 Active Server Pagesについては,すでにいくつかの報道もなされているが,もう一度,説明しておくべきだろう.Active Server Pagesは従来,CGI等で処理していたWeb上のプログラム処理を,サーバー上に配置したスクリプトエンジンで処理しようというものである.使用の用途からいっても,広義におけるCGIの一種といえると思うが,動作の原理は一線を画している.
 CGIはプログラムにHTMLを埋め込むが,Active Server PagesはHTMLにスクリプトを埋め込んで使用する.このように書くと,クライアントのJava Scriptや,Visual Basic ScriptのようにHTMLファイルと一緒にダウンロードされ,ブラウザのスクリプトエンジンによって実行されるモデルを想像するかもしれない.しかし,Active Server Pagesはクロスブラウザをメリットとして上げており,ブラウザに依存して実行されるシステムとは,動作の原理が異なる.


★Active Server Pages--シンプルなサンプル--

 リスト1(test.asp)のサンプルは,シンプルなActive Server Pagesプログラムである.網掛けで表示してある部分がVisual Basic Scriptで記述されているスクリプトである.
 このページがブラウザからリクエストされると,Active Server はクライアントにリスト2(図1)のようなHTMLを応答する.スクリプトの部分がサーバーで実行され,クライアントに処理の終了したHTMLだけが返されるのがわかる.

リスト1:ASPソースコード(test.asp) リスト2:test.aspが生成したHTMLコード
<HTML> <BODY> Active Server Pagesのサンプル <% i = 0 Do While i < 9 i = i + 1 Response.Write(i) Loop %> </BODY> <HTML> <HTML> <BODY> Active Server Pagesのサンプル<BR> 123456789 </BODY> <HTML>
 このようにスクリプティング処理はサーバーで実行するため,クライアントはブラウザを選ばないのが,Active Server Pagesのようなサーバースクリプトの特徴である.Javaやクライアントサイドのスクリプトとは違い,CGIと同じ目的で使うことができる.
 このサンプルプログラムの実行方法は簡単である.Active Server PagesのインストールされたIISのWebパブリッシングディレクトリにファイルをコピーし,ブラウザからHTTP経由で呼び出すだけである.ファイルとして直接,ブラウザで開いた場合は当然スクリプト処理は実行されない.
 Active Serverは拡張子に“ASP”の指定されたファイルがブラウザからリクエストされると,対象のファイルがActive Server Pagesだと判断し,ファイル内に記述されたスクリプトを実行する.複数ページからなるプログラムを実行する場合,HTMLファイルとASPファイルの混在が可能である.この場合,HTMLファイルの拡張子をASPにしても,普通のHTMLファイルと同様に処理する.しかし,マシンの負荷を考えれば,拡張子は“HTM”にするべきだろう.


図1:test.asp




●ユーザーのリクエストに反応するサンプル

 紹介したサンプルはスクリプト処理をおこない,動的にページを作成しているが,ユーザーのアクションに応えることはできない.動的なページの作成例として,ユーザーの選択に応じてリンクするベージを変化させることが考えられる.
 次のサンプルではユーザーの選択に応じて,次に呼び出されるページの背景とコメントを変更している.
 リスト3(図2)はユーザーに選択を促す画面を記述したHTMLコードである.このファイルはサブミットされたときに,color.asp(リスト4)を呼び出す.color.aspにはユーザーがフォームから送信した内容をHTMLに埋め込むためのコードが埋め込まれている.

リスト3:オプションボタンを選択するHTMLファイル(color.htm)
<HTML> <BODY> <FORM METHOD="POST" ACTION="color.asp"> <INPUT TYPE="RADIO" NAME="COLOR" VALUE="RED">RED <INPUT TYPE="RADIO" NAME="COLOR" VALUE="BLUE">BLUE <INPUT TYPE="RADIO" NAME="COLOR" VALUE="YELLOW">YELLOW <INPUT TYPE="SUBMIT" > </FORM> </BODY> </HTML>
図2:color.htm

リスト4:選択された色を表示するASPファイル(color.asp)
<HTML> <BODY BGCOLOR="<% = Request.Form("COLOR")%>"> あなたが選択した色は<% = Request.Form("COLOR")%>です. </BODY> </HTML>

 以下の2つの例は同様の処理をおこなうコードの異なった記述法である.

<% = Request.Form("COLOR")%> <% Response.Write( Request.Form("COLOR"))%>  これらのコードはユーザーが送信したオプションボタンCOLORの内容をHTMLに出力することを指示している.ユーザーがYELLOWを選択したならば,該当の個所はYELLOWの文字列で置き換えられる.結果として表示されるのが,図3のページである.


図3:color.asp(背景が黄色)


●Webデータベースシステム

 さて,本題はデータベースアクセスについてである.インタラクティブなページにとってデータベースアクセスの機能は強力な付加価値になる.いつもきまりきったパターンしか提供できないページに比べ,データベースにリンクできるページはデータの量に応じたバリエーションを用意できるからである.
 もちろん,既存の業務システムをインターネットや,イントラネットに置き換えることも可能である.地元のプロバイダを経由したWAN接続はWebデータベースシステムが威力を発揮するもっとも顕著な例だろう.OCNのスタートにより,中小企業や部門レベルのシステムでも,WANシステムが構築できる可能性が出てきたのである.
 ただ,イントラネットで構築する場合は,他のメリットが見出せないならば,Webデータベースシステムよりも,普通のC/Sシステムでシステム構築をするべきである.他のメリットとして,他の情報系のデータとのリンクや,アプリケーションの配布,メインテンナンス等があげられる.現在,開発ツールベンダはイントラネットシステム構築ツールのリリースに凌ぎを削っている.近いうちにイントラネットの制約はかなり除かれると思うが,それでも,現時点では背負っている制約が大きすぎる.

●ADOを使ったデータベースアクセス

 Active Server Pagesには,ActiveX Data Object(ADO)と呼ばれるデータベースアクセス用のプログラミングオブジェクトが用意されている.RDOをインターネット用にオプティマイズしたともいえるこのオブジェクトは,Active Server Pagesからデータベースにアクセスする場合に威力を発揮する.Active Server Pagesをインストールすると同時にセットアップされるロードマップにも,HTMLによる日本語資料が添付されている(図4).

図4:ADOリファレンス

★テーブルの内容を表示するサンプル

 リスト5,図5に示すサンプルは,ADOを用いてデータベースのテーブルの内容を表示するプログラムである.プログラムの記述方法は難しくない.まず,ADOのConnectionオブジェクトのインスタンスを作成し,Openメソッドを使ってデータベースへのコネクションを確立する.Openメソッドの引数には接続のための情報を指定している.DSNとはODBCのデータソースネームの省略である.
 コネクションが確立されたら,Executeメソッドを使ってSQLコマンドを実行し,Recordsetオブジェクトを作成する.Recordsetオブジェクトの扱いはDAOやRDOに酷似している.以降の,レコードセットのデータをループで1レコードずつ取り出して表示する方法は,Visual Basicとかわらない.
 結果として生成されるHTMLコードがリスト6であり,図5に示されるページである.
リスト5:テーブルを表示するASPファイル(list.asp) リスト6:list.aspにより生成されたHTML
<HTML> <BODY> <% Set dbConnection = Server.CreateObject("ADODB.Connection") dbConnection.Open "DSN=Web SQL;UID=sa;PWD=;DATABASE=Web" Set rs = dbConnection.Execute("SELECT * FROM ACCOUNT") %> <% Do While Not rs.EOF %> <% = rs("ACCNT_NAME") + " " %> <BR> <% rs.MoveNext Loop %> </BODY> </HTML> <HTML> <BODY> 現 金 <BR> 当座小切手 <BR> 現金計 <BR> |
図5:list.asp

 ここではコードをシンプルにするために,ConnectionオブジェクトのExecuteでSQLのSelect文を実行したが,マルチユーザーで使用する環境ならばRecordsetオブジェクトのOpenメソッドを使い,使用するカーソルのタイプとロックの種類を指定すべきである.勘のいい読者ならば,ここまでの説明だけで,データベースアクセスでかなりのことができるのに気づくだろう.

★CreateObjectメソッドによる他オブジェクトの利用

 また,このコードの先頭でCreateObjectメソッドを使用していることに気づいただろうか.Serverオブジェクトによって提供されているこのメソッドこそが,Active Server Pagesが拡張性の高いプラットフォームであることを決定づけている最大の要因である.BackOfficeマガジン前号で紹介したTransaction Serverとの組み合わせでDCOMを利用した分散Webアプリケーションを作成することも可能なのである.
 Visual Basic Script自体は小さな言語仕様だが,Visual Basicで開発したActiveXサーバーコンポーネントをオブジェクトとして呼び出すことで,Visual Basicの持つ機能の多くを利用することができる.Visual Basic自体がコンポーネントを結合するための言語であるが,Visual Basic ScriptはVisual Basic以上にその機能に特化しているといえる.

●セッション管理

 Active Server Pagesの特筆すべき機能に,セッション管理機能がある.もちろん,従来のWebプログラミングでもcookieや,パラメータを利用して擬似的にセッションを維持することは可能だった.Active Server Pagesのセッション機能もcookieを使ってユーザーの特定をしていることは同様である.しかし,各リクエスト毎にセッションを切断するWWWサービスにおいて,cookieを利用したセッション管理は断続的に接続される疑似セッションであった.
 Active Server Pagesはサーバー上にメモリ空間を確保し,ページをまたぐ真のセッションを実現する.cookieを利用するのは,そのユーザーが本当にその領域にアクセスする権利があるかどうかを確認するためである.セッションの切断は,任意に設定されるタイムアウトの経過時間,新しいページのリクエストがなかった場合と,コードで明示的に指示された場合におこなわれる.
 セッションが維持できる最大のメリットは,ページ間でのオブジェクトの共有ができることである.値だけならば,cookieやパラメータによっても受け渡すことができるが,オブジェクトとなるとそうはいかないからである.

★セッションを使ってレコードセットを共有するサンプル

 リスト7,8,図6,7のサンプルはセッションを利用してページ間でレコードセットを共有するサンプルである.作成しているレコードセットは前のサンプルとまったく同じものである.ただ,ここでは最初のページでレコードセットの作成を行ない,次のページでその内容を表示している.
 Recordsetオブジェクトをセッションの領域に格納しているのが,リスト7のコードである.

リスト7:レコードセットを作成し,Session変数に格納(list_session.asp)
<HTML> <BODY> <% Set dbConnection = Server.CreateObject("ADODB.Connection") dbConnection.Open "DSN=Web SQL;UID=sa;PWD=;DATABASE=WebDB" Set rs = dbConnection.Execute("SELECT * FROM ACCOUNT") Set Session("ACCOUNT_Table") = rs Session("Mem") = "この文字列をSession変数Memに格納します" %> レコードセットを作成し,Session変数に格納しました.<BR> 内容を表示するには下のリンクをクリックしてください.<BR> <A HREF="list_session2.asp">レコードセットの表示</A> </BODY> </HTML>

Set Session("ACCOUNT_Table") = rs

 また,次のコードは文字列をSession変数に代入している.

Session("Mem") = "この文字列をSession変数Memに格納します"

これらを取り出しているのが,リスト8の次の2行である.

リスト8:Session変数に格納されている文字列とレコードセットを利用(list_session2.asp)
<HTML> <BODY> <% Set rs2 = Session("ACCOUNT_Table") Response.Write(Session("Mem")) %> <BR> <% Do While Not rs2.EOF %> <% = rs2("ACCNT_NAME") + " " %> <BR> <% rs2.MoveNext Loop %> </BODY> </HTML>

Set rs2 = Session("ACCOUNT_Table")
Response.Write(Session("Mem"))

 最初の行は格納されているレコードセットを,オブジェクト変数に戻している.もちろん内容は,値としてではなく,参照ポインタが渡される.
 2行目は前のページで代入された文字列をページに出力している.結果として表示されるページが図7である.
 このようにSession変数に格納したものを,各ページで呼び出すことができる.

図6:list._sessionasp

図7:list._session2asp

●Advanced Data Connector

 最後にAdvanced Data Connector(ADC)について触れておこう.断っておくが,ADCはテクノロジーの種類としてActive Server Pagesに所属するものではない.クライアントサイドActiveXテクノロジーに属するものである.ADC自体がActiveXコントロールであることからも,それは明確である.
 しかし,Webによるデータベースアクセスの手段として,Active Server Pages以上の可能性をもっている.Webデータベースシステムの本命を,“Java+JDBC”だと私は考えているが,ADCはそれに対抗するものである.現在,停滞しているJavaの進歩を尻目に,Microsoftがすでにこれだけ動作するものを用意してきたことは,驚くべきことである.
 今後,このシステムの充実次第ではJDBCへの移行を見合わせようかという誘惑にかられる.このシステムが持つ最大の欠点は,それがActiveXコントロール対応ブラウザでしか動かないということだろう.だが,これがどれだけ欠点であり続けるかは,今後のブラウザの動向に依存する.また,Javaによるクロスプラットフォームがすでに幻想となりつつある現状において,決定的なマイナスとはなり得ないだろう.

★HTTP経由のデータベースアクセス
 ADCはクライアントにインストールされたActiveXコントロールが,サーバーのデータベースのODBCを直接参照する.ODBCではなくHTTPを経由するところが,Visual J++でRDOを使用した場合との違いである.RDOはODBCのデータソース名にクライアントのデータソースネームを指定するが,ADCはインターネットサーバー名とサーバーマシンのODBCデータソース名を指定する.
 また,クエリーの結果であるレコードセットがサーバーでなく,クライアントに作成されることがActive Server PagesのADOとの違いである.このレコードセットは更新可能で,しかも,コントロールへのデータ連結が可能である.
 ただ,ADCに付属しているサンプルプログラムは更新機能がインプリメントされていたものの,実際には動作しなかった.更新方法としてレコードセットの変更をサブミットする方法と,連結されているGRIDコントロールをアップデートする方法の2種類がサンプルには記述されている.しかし,その両方とも動作しない.
 しかし,ADCに対してSQLのUPDATE文を実行したところ,これは正常に更新処理をおこなった.しかも,データ送信の際にページの更新をすることなくである.つまり,ページを表示した状態で,複数のUPDATE文を実行し,複数レコードの同時更新ができるのである.<FORM>タグによる送信の限界に頭を悩ませていたWebデータベースデベロッパーにとって,これは大きな福音である.

★ADCを使ったサンプルプログラム
 リスト9と図8で示すプログラムは,Microsoftが提供するサンプルに更新機能を独自に追加したものである.コード部を網掛けにしてあるが,これはクライアントサイドのVisual Basic Scriptであることに注意してほしい.ローカルにダウンロードされ,ブラウザの言語エンジンが処理するスクリプトである.このサンプルはHTMLファイルであるため,ここに表示した内容そのものがブラウザには読み込まれる.  <BODY>タグの初期化処理でADCのプロパティを設定し,レコードセットを作成している.ADCのパラメータBINDINGSにGRIDを設定しているため,レコードセット作成するだけで,データの表示がおこなわれる.
 データの更新はテキストボックスに入力された内容からUPDATE文を動的に生成し,実行している.更新した結果を表示するためにレコードセットを再生成しているが,スペック通りレコードセットによる更新ができれば,この処理は必要なくなる.リリース版に期待したい.
(リスト9の内容は付録CD-ROMの\VBMAG\ASPSディレクトリに収録しています:編集部)

リスト9:ADCのサンプルコード
<HTML> <BODY LANGUAGE="VBS" onload = "init"> 商品コード<INPUT NAME="TEXT1"> 商品名<INPUT NAME="TEXT2"> <OBJECT ID="GRID" WIDTH=700 HEIGHT=200 CLASSID="CLSID:BC496AE0-9B4E-11CE-A6D5-0000C0BE9395" CODEBASE="HTTP://montevideo/MSADC/Samples/Sheridan.cab"> </OBJECT> <INPUT TYPE=BUTTON NAME="MovePrev" VALUE="Prev"> <INPUT TYPE=BUTTON NAME="MoveNext" VALUE="Next"> <INPUT TYPE=BUTTON NAME="Update" VALUE="Update"> <OBJECT CLASSID="clsid:9381D8F2-0288-11d0-9501-00AA00B911A5" ID=ADC HEIGHT=10 WIDTH = 10 CODEBASE="HTTP://montevideo/MSADC/msadc10.cab"> <PARAM NAME="BINDINGS" VALUE="GRID;"> </OBJECT> <SCRIPT LANGUAGE= "VBS"> SUB MoveNext_OnClick ADC.MoveNext END SUB SUB MovePrev_OnClick ADC.MovePrevious END SUB SUB Update_OnClick ADC.SQL = "UPDATE Syohin Set syohin_mei = '" +TEXT2.VALUE+ "' where syohin_code = " + _ TEXT1.VALUE ADC.Refresh ADC.SQL = "Select * from Syohin" ADC.Refresh END SUB SUB init ADC.Server = "http://montevideo" ADC.Connect = "DSN=order;UID=sa;PWD=" ADC.SQL = "Select * from Syohin" ADC.Refresh END SUB </SCRIPT> </BODY> </HTML>

図8:ADCのサンプル--GRIDコントロールにデータを表示し,データの更新も可能--


VB Magazine ライブラリ | Visual Basicコースホームページ
int21 ホームページ | PCDN ホームページ


PCDN LOGO

HTML Converted by Falcon/礒山 賢司