日本オラクル クロスインダストリー統括本部
OracleDirect テクニカルサービスグループ
大田 浩


目次
はじめに
スマートクライアントとは
Oracle Data Provider for .NETのインストール
サンプルアプリケーションのインストール
データベースへの接続 - コネクション
データの取得 - 接続タイプ
データの取得 - 接続型データアクセス
データの取得 - 非接続型データアクセス
BLOBデータへのアクセス
XMLの扱い
トランザクション


 はじめに

「意外と簡単!? .NETでOracle」シリーズは、Microsoft Visual Studio.NETを使用してOracle10g対応アプリケーションをこれから開発されるかた向けに作成しております。実際のサンプルアプリケーションを提供することにより、単なるコーディングTipsにとどまらず、より実践的なアプリケーション開発の資料として構成するようにしております。
.NETからオラクルへの接続にはさまざまな方法が存在しますが、「意外と簡単!? .NETでOracle」シリーズではオラクル社が提供している.Oracle Data Provider for .NETを利用しており、開発言語はVisual Basic.NETを使用しております。今回のサンプルアプリケーションの説明はポイントとなる部分のみの説明になりますので予めご了承ください。
「意外と簡単!? .NETでOracle」シリーズが.NET開発者でオラクルを利用したい方のシステム構築の一助になれば幸いです。

  「意外と簡単!? .NETでOracle」シリーズは以下の3つの構成を予定しています

  1. スマートクライアント編(本書)
  2. Web アプリケーション編「ASP.NET」
  3. OO4O(Oracle Objects for OLE)からODP.NET移行編

  「意外と簡単!? .NETでOracle」シリーズの「スマートクライアント編」は、以下の9つの内容から構成しております

  1. スマートクライアントとは
  2. Oracle Data Provider for .NETのインストール
  3. サンプルアプリケーションのインストール
  4. データベースへの接続 - コネクション
  5. データの取得 - 接続型データアクセス
  6. データの取得 - 非接続型データアクセス
  7. BLOBデータへのアクセス
  8. XMLデータの取り扱い
  9. トランザクション処理

  「意外と簡単!? .NETでOracle」シリーズにおける開発環境

データベース・サーバー
OS:Microsoft Windows 2000 Professional + SP4
RDBMS:Oracle Database 10g Standard Edition for Windows
アプリケーション・サーバー
OS:Microsoft Windows 2003 Enterprise
APサーバー:Microsoft Internet Information Services 6.0
開発クライアント
OS:Microsoft Windows 2000 Professional + SP4
開発ツール:Microsoft Visual Studio .NET 2003



 スマートクライアントとは

スマートクライアントとは、今までのC/S(クライアント/サーバ)システムのリッチクライアントとウェブアプリケーション(クライアントにウェブブラウザを使用するアプリケーション)の運用管理の容易さの両方を兼ねそろえたクライアントアプリケーションになります。具体的には「XML Webサービス」を呼び出すリッチクライアントをスマートクライアントと呼びます。以下にXML Webサービスについての概要と、スマートクライアントの利点を説明します。

メモ:リッチ・クライアントとは、従来のC/Sシステムの長所であるリッチな「ユーザー・インターフェイスの表現力」、「操作性」、「機能」を備えたクライアントになります。


  XML Webサービスとは

XML Webサービスを説明する前に、Webサービスについて説明したいと思います。Web サービスとは、インターネットを通じてアプリケーションどうしを結び付け、ソフトウェアの機能をインターネットを通じて利用できるようにしたものです。XML WebサービスとはXMLをベースにしたWebサービスの利用を前提にしております。


  C/Sシステム、Webアプリケーション、スマートクライアントとの違い

以下に、スマートクライアントアプリケーション、C/Sアプリケーション、Webアプリケーションの動作環境の違いと特徴を説明します。


■特徴
種類 アプリケーションの配布 クライアントの特徴
スマートクライアント ノータッチデプロイメントを使用することにより、不要。 機能やGUIが充実したユーザーインターフェースを使用したクライアント。(リッチ・クライアント)
Webアプリケーション HTMLをクライアントブラウザで表示するため、不要。 機能やGUIが貧弱なクライアント。(シン・クライアント)
C/Sアプリケーション 必要なアプリケーション・コンポーネントのインストールが必要。 機能やGUIが充実したユーザーインターフェースを使用したクライアント。(リッチ・クライアント)

以上のようにスマートクライアントではWebアプリケーション配布の容易性と、C/Sアプリケーションのリッチクライアントの両方を兼ねそろえたアプリケーションの開発が可能です。


  スマートクライアントの利点

スマートクライアントとはXML Webサービスを呼び出すクライアントになります。スマートクライアントによるアプリケーション開発の利点は以下の点が挙げられます。
  • HTTPプロトコルを使用することにより、特殊なデータプロトコルを必要とせず、HTTPプロトコルを使用可能なサーバー・クライアントはWebサービスへのアクセスが可能です。
  • XML Webサービスは、HTTP、 XML、SOAP(Simple Object Access Protocol)などの標準的なWebプロトコルとデータ形式を使用して通信を行うため、プラットフォームや言語に依存しないサービスを提供できます。
  • OracleへのデータアクセスをWebサービス側で行うことにより、クライアント側にOracleクライアント・ソフトウェアをインストールする必要がなく、アプリケーションの配布もノータッチデプロイメントを使用することにより容易になり、アプリケーションの配布、運用/管理の手間が省かれます。


 Oracle Data Provider for .NETのインストール

今回のサンプルアプリケーションではOracleデータベースへの接続ミドルウェアに Oracle Data Provider for .NET(以下 ODP.NET)を使用しています。
ODP.NETはOTN Japan(Oracle Technology Network Japan)の以下のURLよりダウンロード可能です。

http://otn.oracle.co.jp/software/tech/windows/odpnet/index.html


上記のページよりダウンロードを行ってください。ダウンロードファイルはODAC10g.exeになります。ダウンロード後は以下の手順でインストールを行ってください。


ODP.NETのインストール手順

1.   ODAC10g.exeを任意の一時フォルダにダウンロードしてください。
メモ:"Tmp"という名前がついたフォルダにはダウンロードしないでください。

2.   ODAC10g.exeを実行して、解凍してください。

3.   解凍したフォルダの下のDisk1以下にあるsetup.exeを実行して、Oracle Universal Installer(OUI)を起動してください。
OUIが起動しましたら、「次へ」ボタンをクリックしてください。

4.   ファイル場所の指定画面が表示されましたら、インストール先のORACLE_HOMEとパスを指定してください。通常、標準のままで問題ありません。

5.   使用可能な製品コンポーネントが表示されます。ここでは、「Oracle Data Provider for .NET 10.1.0.2.0」と「Oracle Services For Microsoft Transaction Server 10.1.0.2.0」を選択します。他に必要なコンポーネントが一緒に選択し、「次へ」をクリックしてください。
Oracle Services For Microsoft Transaction Serverは今回のサンプルで使用しております、XML Webサービス上でトランザクション制御を行う場合に必要となります。

6.   Oracle Services For Microsoft Transaction Serverのポート番号の指定画面が表示されますので、そのまま「次へ」をクリックしてください。

7.   サマリー画面が表示されますので、「インストール」をクリックしてください。

8.   インストール終了後に Configuration Assistant画面が表示されますので「次へ」をクリックして下さい。

9.   ネーミングメソッドの選択画面が表示されますので、「ローカルネーミング」を選択し(デフォルトで選択済み)、「次へ」をクリックします。

10. ネットサービス名の構成−サービス名の画面が表示されますので、グローバルデータベース名を入力して、「次へ」をクリックしてください。

11. ネットサービス名の構成−プロトコルの選択画面が表示されますので、デフォルトでチェックされているTCPを選択して、「次へ」をクリックしてください。

12.  ネットサービス名の構成−TCP/IPプロトコル画面が表示されますので、ホスト名にOracleデータベースがインストールされているサーバーのホスト名、もしくはIPアドレスを入力して、「次へ」をクリックしてください。ポートの指定はネットワークの環境に応じて設定してください。

13.  ネットサービス名の構成−テスト画面が表示されましたら、テストを行うか選択後に「次へ」をクリックしてください。

14. 「テストを実行する」を選択しますと、ネットサービス名の構成−接続画面にテスト結果が表示されます。テストが失敗した場合は、サービス名やホスト名などの指定が間違えてないか確認後にもう一度テストを行ってください。

15. テスト完了後(テストをしない場合は、ネットサービス名の構成−テスト画面で次へをクリック後)ネットサービス名の構成−ネットサービス名画面が表示されますので、任意のネットサービス名を入力して次へをクリックしてください。
この画面で入力するネットサービス名を使用して、ODP.NETはORACLEデータベースへ接続を行います。

16. 他のネットサービス名を構成する場合は、「はい」を選択してください。今回は「いいえ」を選択して、次へをクリックした場合の説明を行います。

17. ネットサービス名の構成が終了しました。と表示されますので、「次へ」をクリックしてください。

18. ネットサービス名の構成が完了しました。と表示されましたら、「次へ」をクリックしてください。

19. Oracle Net Configurationが完了しました。と表示されましたら、「終了」をクリックしてください。

20. Oracle Universal Installerの画面に戻りますと、「インストールの終了」画面が表示されていますので、終了をクリックしてください。「終了しますか?」とダイアログが表示されますので、OKをクリックしてください。
以上でODP.NETのインストールが完了です。

21. インストール終了後、一時フォルダ上のODAC10g.exeおよび解凍したファイルを削除してください。

上記の作業でODP.NETがインストールされます。インストール後はODP.NETをVisual Studio.NETから使用するための設定が必要になります。


ODP.NETをVisual Studio.NETから使用するための手順

1.   参照設定
  • Visual Studio.NETで新規にプロジェクトを作成し、ソリューション・エクスプローラーより、「参照設定」を右クリックして「参照の追加」を選択してください。
  • 参照の追加画面でOracle.DataAccess.dllを選択し選択ボタンを押しますと、選択されたコンポーネントにOracle.DataAccess.dllが表示されますので、「OK」ボタンを押して下さい。
  • 上記の設定をしますと、ソリューション・エクスプローラーに以下のようにOracle.DataAccessが追加されます。

2.   ODP.NETコントロールをツールボックスに追加
  • ツールボックスウィンドウで右クリックをし、アイテムの追加と削除を選択します。
  • ツールボックスのカスタマイズ画面で以下の4つのコンポーネントをチェックし、OKボタンを押してください。
    • OracleCommand
    • OracleCommandBuilder
    • OracleConnection
    • OracleDataAdapter

メモ:名前空間がOracle.DataAccess.Clientのコンポーネントを選択してください。System.Data.OracleClientに同名のコンポーネント名が存在しますが、そちらはMicrosoft社が提供しているOracleへ接続するための.NETプロバイダーになります。


3.   Visual Studio .NETと連動したODP.NETヘルプのインストール
  • ORACLE_HOME ディレクトリ下にODP.NETディレクトリが存在します。更にその下位層のディレクトリにhelp\jaというディレクトリがあります。そのディレクトリ内にインストーラファイルDataProviderHelp.msiが存在しますので、必要に応じてダブルクリックしてHELPファイルをインストールして下さい。
メモ:Oracle_Homeが C:\oracle\product\10.1.0\Db_1の場合は、 C:\oracle\product\10.1.0\Db_1\ODP.NET\help\ja ディレクトリにDataProviderHelp.msiが存在します。
  • Visual Studio .NET を起動し、メニューの「ヘルプ」−>「ダイナミックヘルプ」を選択。
  • 最下部 「Visual Studioのヘルプのインストール」を選択。参照項目の「Visual Studio .NET連結ヘルプコレクション マネージャ」をクリック。
  • 下部の「VSCC に含めることのできるコレクション」の“ODP.NET Help”にチェックし、「VSCCの更新」をクリックしてください。
  • Visual Studio .NET 再起動後にヘルプが参照可能になります。


 サンプルアプリケーションのインストール

サンプルアプリケーションは以下のサイトよりダウンロードできます。

http://otn.oracle.co.jp/easy/dotnet/index.html

ダウンロードファイル(sample.zip)を任意の一時フォルダに保存し、解凍してください。解凍しますと 「data」、「StockManagement」、「WebServiceStockManagement」という3つのディレクトリが作成されます。今回のサンプルアプリケーションでは以下のように データベース・サーバー、Webアプリケーション・サーバー、クライアントの3つの構成になります。ダウンロードファイルを解凍後にそれぞれの端末で以下の作業を行ってください。


メモ:今回のサンプルを動作させるためにOracle Database 10gをインストールし、データベースを構築しておく必要があります。Oracle Database 10gのインストール、初期データベースの作成などについては、OTN Japan上の「意外と簡単!? Oracle Database 10g」をご参照下さい。
http://otn.oracle.co.jp/beginner/oracle10g/index.html


  サンプルデータ・パッケージの作成(データベース・サーバーでの設定)

今回のシステムで使用しているサンプルデータとパッケージをOracleがインストールされたデータベース・サーバー上にて、以下の手順で作成します。

1.   ディレクトリの設定
今回のサンプルアプリケーションでは商品マスタ上の商品イメージを画像ファイルとして管理しております。サンプルデータ作成時にビットマップファイルを取り込みます。そのためにビットマップファイルが保管されているディレクトリを読み込み可能に設定する必要があります。ダウンロードファイル(sample.zip)を解凍すると作成されるdataディレクトリをOracle Database 10gがインストールされているサーバー上の任意のディレクトリにコピーして以下のコマンドをSQL*Plus上で実行してください。
(dataディレクトリを c:\temp\dataにコピーし、ユーザーscottに対してディレクトリを読み込み可能にする設定のサンプル)
  • sqlplus system/<password>(SQL*Plusにsystemユーザーでログイン)
  • create directory imgdir as ‘c:\temp\data’;
  • grant read on directory imgdir to scott;
メモ:create directoryにより、実際にディレクトリが作成されるわけではなく、Oracleで管理するためのディレクトリオブジェクトを作成しております。

2.   テーブルとサンプルデータのインストール
dataディレクトリのinstall.sqlをSQL*Plusで実行しますと、テーブルとパッケージが作成されます。以下のようにinstall.sqlを実行してください。
  • sqlplus scott/tiger (SQL*Plusにログイン)
  • @install.sql (テーブルとパッケージの作成スクリプトSQLの実行)
  • exit (SQL*Plusの終了)
メモ:上記のサンプルでは SCOTTユーザーでログインしていますが、任意のユーザー名でログインしてください。また、1の作業で作成したディレクトリオブジェクトを削除したい場合は、SQL*Plusにsystemユーザーでログインしなおし、drop directory imgdir; と入力してください。


  Internet Information Services(IIS)の設定(アプリケーション・サーバー上での設定)

ダウンロードファイル(sample.zip)を解凍後に作成されるWebServiceStockManagementというディレクトリをWebサーバー上のInternet Information Services(IIS)のrootディレクトリ下にディレクトリごとコピーしてください。コピー後は以下のようなディレクトリ構成になります。


コピーが終わりましたら、「コントロール・パネル」の管理ツールより「インターネット・サービス・マネージャ」を起動してください。WebServiceStockManagementフォルダの設定を変更します。Internet Infomation Servies(IIS)の管理画面を開き、以下のようにWebServiceStockManagementフォルダを右クリックしてください。


メニューのプロパティを選択しますと、以下のプロパティ設定の画面が表示されます。


上記の画面で「アプリケーションの設定項目」にある「作成」ボタンをクリックするとアプリケーションの設定が行われます。作成されたら「OK」をクリックしてプロパティ・ウィンドウを終了してください。


  Visual Studio .NETでソリューションを開く(開発クライアント上での設定)

ダウンロードファイル(sample.zip)を解凍後に作成されるStockManagementというディレクトリをVisual Studio .NET 2003がインストールされた端末上の任意のディレクトリ下にディレクトリごとコピーしてください。コピー後にVisual Studio .NETでソリューションファイルを開きます。任意のディレクトリにコピーしたStockManagementディレクトリ下のStockManagement.slnファイルをダブルクリックでしますと、Visual Studio .NETが起動されます。ソリューション・エクスプローラーには以下の2つのプロジェクトが開かれた状態になっております。


2つのプロジェクトはそれぞれ以下のような構成になっております。
  • StockManagement
    クライアント側 WindowsFormアプリケーション。
  • WebServiceStockManagement
    Webサービス側 XML Webサービスアプリケーション。
メモ:データアクセス部分はWebServiceStockManagementプロジェクトのServiceStockManagement.asmxに記述されています。

上記の設定で必要なファイルがインストールされ、実行可能になります。今回作成されるアプリケーションの実行ファイルはStockManagementディレクトリ下のbinディレクトリにStockManagement.exeとして作成されます。このファイルをInternet Infomation Servies(IIS)上に公開することによって、アプリケーションをクライアントに配布することなくInternet ExplorerなどのWEBブラウザからURLを指定することにより、アプリケーションを実行することが可能です(ノータッチデプロイメント)。以下の手順でアプリケーションをInternet Infomation Servies(IIS)上に公開します。

Webサーバー上のInternet Information Services(IIS)のrootディレクトリ下にStockManagementというディレクトリを作成してください。作成後は以下のようなディレクトリ構成になります。


StockManagementディレクトリを作成後、そのディレクトリにStockManagement.exeファイルをコピーしてください。コピー後「コントロール・パネル」の管理ツールより「インターネット・サービス・マネージャ」を起動してください。StockManagementフォルダの設定を変更します。Internet Infomation Servies(IIS)の管理画面を開き、以下のようにStockManagementフォルダを右クリックしてください。


メニューのプロパティを選択しますと、以下のプロパティ設定の画面が表示されます。


上記の画面で「アプリケーションの設定項目」にある「作成」ボタンをクリックするとアプリケーションの設定が行われます。作成されたら「OK」をクリックしてプロパティ・ウィンドウを終了してください。以上でWEBサーバー上での設定は終わりです。クライアント端末より Internet Explorerを起動し、以下のアドレスを入力してください。

http://<WEBサーバーのコンピュータ名、もしくはIPアドレス>/StockManagement/StockManagement.exe


アドレスを入力しますと在庫管理システムが起動されます。


在庫管理システムの使用方法は以下のサイトより操作説明書をダウンロードできますのでそちらをご覧下さい。

http://otn.oracle.co.jp/easy/dotnet/index.html

これから実際にODP.NETを使用したアプリケーション開発の方法をサンプル・アプリケーションのコードを参照しながら説明します。


 データベースへの接続 - コネクション

Oracleデータベースへ接続するためのステップは以下のようになります。接続以外の部分に関しては、サンプルアプリケーションのコードの一部を参照しながらODP.NETにおける開発の主要な部分について説明します。
  1. OracleConnectionの定義
  2. コネクション文字列の設定とデータベースへの接続

  OracleConnectionの定義

コネクション変数を定義する前に、ImportsステートメントでODP.NETの名前空間を定義します。そうすることにより、ODP.NET変数の宣言部分の文字列を短くすることが出来ます。

1.   名前空間の宣言
Importsステートメントを使用し、ODP.NETの名前空間を追加します。

<ソース ServiceStockManager.asmx.vb - 宣言部>

Importsステートメント宣言部に以下の2つのコードを追加します。

Imports Oracle.DataAccess.Client
Imports Oracle.DataAccess.Types

2.   コネクションオブジェクトの宣言
名前空間を定義してあるので、以下のコードでコネクションオブジェクトを定義可能です。

<ソース ServiceStockManager.asmx.vb − 宣言部>
Private Cnn As New OracleConnection

名前空間を定義していない場合には、以下のようになります。

Private cnn As New Oracle.DataAccess.Client.OracleConnection


  コネクション文字列の設定とデータベースへの接続

1.   コネクション文字列の設定
ConnectionStringにOracleへの接続の文字列を入力します。

<ソース ServiceStockManager.asmx.vb−DbConnect関数, DBOpen関数>

データベースに接続するユーザ名を“user id”に、パスワードを”password”に、Oracle Data Provider for .NETのインストールで説明しました、ネットサービス名を”data source”に設定します。

Cnn.ConnectionString = "user id=scott;password=tiger;data source=orcl"

2.   データベースへの接続
実際のデータベースへの接続は、Openメソッドで行います。

<ソース ServiceStockManager.asmx.vb−DBOpen関数>
cnn.Open()

ポイント:後で説明します接続型ではコネクション文字列を設定後にOpenメソッドを使用する必要があります。非接続型ではデータ取得時に自動的にOpen , Closeを行いますので、Openメソッドを使用する必要がありません。サンプルの DbOpen関数は接続型を使用する場合に、DbConnect関数は非接続型使用時にそれぞれ呼び出しています。


 データの取得 - 接続タイプ

Oracleデータベースへのデータアクセスの方法として接続型と非接続型の2つが存在します。それぞれODP.NETで使用するオブジェクトが違います。


また、接続型/非接続型の特徴として以下の点が挙げられます。

接続タイプ 参照系SQLの実行 更新系SQLの実行 トランザクション
接続型 データ取り出し期間中、データベースに常に接続。 データの更新が接続中に発行できるので容易。 トランザクション制御は容易。
非接続型 データ取得時のみデータベースに接続。 一度データベースへの接続が切断されるので複雑。 非接続中の更新なども考慮に入れる必要があるため複雑。


 データの取得 - 接続型データアクセス

接続型データアクセスとは、データベースに接続したままの状態でデータを読み書きする手法です。今回のサンプルアプリケーションようなXML Webサービスでのデータアクセスの場合は、Webサービス側でOracleからデータを取得した後に、コネクションを切断してデータをクライアントに返すような流れになりますので(後述する非接続型データアクセス)、接続型アクセスを使用している部分はログイン時のID、パスワードチェックのロジック部分のみになります。ODP.NETでの接続型データアクセスの方法は、以下の手順になります。
  1. OracleCommandオブジェクトを使用し、SQLの定義。
  2. OracleDataReaderオブジェクトを使用し、データの読み取り。

  OracleCommandオブジェクトの使用

OracleCommandを使用し、実行するSQLを定義するには以下の手順が必要になります。

1.   OracleCommandオブジェクトの宣言 - ServiceStockManager.asmx.vb - 宣言部
以下のようにOracleCommandオブジェクトを宣言します。

<ソース ServiceStockManager.asmx.vb - 宣言部>
Private cmd as New OracleCommand

2.   OracleCommandオブジェクトで使用するConnectionの設定 - ServiceStockManager.asmx.vb. - DbOpen()
OracleCommandオブジェクトで使用するConnectionを以下のように設定します。

<ソース ServiceStockManager.asmx.vb - DbOpen関数, DbConnect関数>
cmd.Connection = cnn

3.   SQLの定義
OracleCommandオブジェクトのCommandTextプロパティで発行するSQLを定義します。

<ソース ServiceStockManager.asmx.vb - doLogin関数>

上記のSQLではバインド変数が使用されています。:が前についた個所がバインド変数になります(:p_EmpCode)。

sSql = “Select password From emp where empcode=:p_EmpCode”
cmd.CommandText = sSql

バインド変数については次項目で説明します。

4.   バインド変数の設定
バインド変数の設定はOracleParameterオブジェクトを使用します。OracleParameterを使用したコードは以下のようになります。

<ソース ServiceStockManager.asmx.vb - doLogin関数>
cmd.BindByName = True
Dim paraEmpcd As OracleParameter = _
          cmd.Parameters.Add("p_EmpCode", sEmpCode)

パラメータの設定方法には以下の2つの種類があります。
  • 位置パラメータ(デフォルト)
    位置パラメータを使用する場合は、OracleParameterオブジェクトの追加順をSQLで指定されたパラメータ順にする必要があります。SQLで指定されたパラメータとOracleParameterで指定するパラメータ名が同一である必要はありません。
  • 名前指定パラメータ
    名前指定パラメータとは、上記のサンプルソースのように、
    cmd.BindByName = True
    と OracleCommandオブジェクトのBindByNameプロパティをTrueに設定します。名前指定パラメータの場合はOracleParameterオブジェクトの追加順は引数順にする必要はありませんが、パラメータ名とOracleParameterで指定するパラメータ名が同一である必要があります。


  OracleDataReaderオブジェクトの使用

OracleDataReaderはOracleCommandで定義したSQLの実行結果を取得します。データの取得、読込の手順は以下のようになります。

1.   OracleDataReaderオブジェクトの宣言
以下のコードでOracleCommandで定義したSQLの実行結果をOracleDataReaderで取得しています。

<ソース ServiceStockManager.asmx.vb - doLogin関数>
Dim rdr As OracleDataReader = cmd.ExecuteReader

2.   取得したデータの読込
以下のコードでOracleDataReaderオブジェクトにてデータを読込、値を取得しています。 Readメソッドを使用してレコード単位でデータを読み込んでいます。

<ソース ServiceStockManager.asmx.vb - doLogin関数>
If rdr.Read Then
     If rdr("password") = sPassword Then
           bRet = True
     Else
           sMsg = "パスワードが違います。"
           bRet = False
     End If
Else
     sMsg = "社員コードが登録されていません。"
     bRet = False
End If

ポイント:OracleDataReaderは前方向スクロールのみです。Readメソッドを使用することにより、次レコードに移動します。また、読み出し専用で更新が出来ません。

3.   OracleDataReaderとOracleConnectionのクローズ
処理が終了した場合は開発者が明示的にOracleDataReaderとOracleConnectionを以下のようにClose()メソッドを使用し、クローズします。

rdr.Close()
cnn.Close()

ポイント:ODP.NETでは複数のOracleDataReaderを同時に開く事が出来ます。この機能は複数のアクティブな結果セット−Multiple Active Result Sets "MARS"という略語で呼ばれています。ADO.NET 1.0と1.1では以下のように複数DataReaderを開くとエラーがスローされますが、ODP.NETでは可能となっております。

< Multiple Active Result Sets "MARS" サンプルコード>
(以下のコードはサンプルアプリケーションのソースにはありません。)


 データの取得 - 非接続型データアクセス

非接続型データアクセスでは、Oracle上のデータのスナップショットコピーをDatasetオブジェクトにコピーします。スナップショット取得時のみOracleへ接続し、取得後はOracleへのコネクションは自動的に閉じられます。取得後接続を閉じた後でもDatasetオブジェクトでデータを参照できます。
今回のサンプルシステムでは主にXML Webサービスからデータを取得し、結果をDatasetオブジェクトにコピーしてクライアント側で結果を表示するような処理を行っています。ODP.NETでの非接続型データアクセスの方法は、以下の手順になります。
  1. OracleCommandオブジェクトを使用し、SQLの定義。
  2. OracleDataAdapterオブジェクトを使用し、Oracleからデータを取得し、DataSetに格納します。

ポイント:DataSetオブジェクトは、1つ以上のデータソースからのデータのローカルコピーを保存するオブジェクトです。データソースのデータを更新する場合は、DataAdapterを使用してデータソースに再接続し、更新を行います。


  OracleDataAdapterオブジェクトの使用

OracleDataAdapterはOracleCommandで定義したSQLの実行結果をDataSetに格納します。データの取得、読込の手順は以下のようになります。
以下のコードでOracleCommandで定義したSQLの実行結果をOracleDataAdapterがDatasetオブジェクトに格納します。

<ソース ServiceStockManager.asmx.vb - GetEmployeeListメソッド>

上記のコードでは、非接続型固有のデータの取得方法について説明します。

1.   OracleDataAdapterの宣言
OracleDataAdapterの宣言時にOracleCommandオブジェクトを引数として設定します。

Dim da as New OracleDataAdapter(cmd)

2.   DataSetオブジェクトへデータを格納
DataAdapterのFillメソッドを使用しDataSetオブジェクトへデータを格納します。以下のようなコードになります。

If dsList.Tables.Contains("EmployeeList") Then _
     dsList.Tables("EmployeeList").Clear()
da.Fill(dsList, "EmployeeList")

Fillメソッドの2番目の引数は、作成されるDataTableオブジェクトの名前になります。DataSetオブジェクトは複数のDataTableオブジェクトを格納出来るので、名前を使用することによりどのテーブルを参照するのか指定が出来ます。上記のサンプルでは EmployeeListテーブルオブジェクトがdsListデータセット内に存在するかチェックしています。存在する場合は、そのテーブルオブジェクトの中身をクリアしてからFillメソッドでデータを代入しております。既存のデータが存在する場合はFillするとデータは上書きではなく追加になるのでご注意ください。


 BLOBデータへのアクセス

今回のサンプルアプリケーションでは、商品マスタの一部の項目にBLOB型を使用しており、商品の写真を格納しています。XML サービスでのBLOBデータの受け渡しですが、以下のようになります。

  BLOBデータの受信

BLOBフィールドからデータを取得し、PictureBoxへ表示する手順を説明します。

1.   BLOBデータをDatasetに格納
以下のコードのように、BLOBフィールドをDataSetに格納します。

<ソース ServiceStockManager.asmx.vb - GetProductDataメソッド>

商品マスタ(Productテーブル)のProductImageフィールドがBLOBで定義されている画像フィールドになります。DataSetオブジェクトに格納するときには、BLOBフィールドの場合でも特に意識する必要はありません。

2.   DataSetオブジェクトに取得したBLOB型データをPictureBoxへ表示
以下のコードのようにDataSetオブジェクトへ格納されたBLOB型データをPictureBoxへ表示します。

<ソース fmProduct.vb - GetProductDataメソッド>

DataSetオブジェクトから画像情報をByte配列に格納し、さらにMemoryStreamへ保存します。Image.FromStreamメソッドを使用しPictureBoxのImageオブジェクトに代入し、表示するために、以下のコーディングを行っています。

Dim byteImage() As Byte = .Item("productimage")
Dim ms As New MemoryStream(byteImage)
PictureBoxProduct.Image = Image.FromStream(ms)


  BLOBデータの更新

クライアントのPictureBoxの画像をXML Webサービスを通してOracleのBLOBフィールドに格納する方法は以下のようになります。

1.   PictureBoxの画像をByte配列に格納
以下のコードのように、PictureBoxの画像をByte配列に格納します。

<ソース fmProduct.vb - GetProductDataメソッド>

MemoryStreamオブジェクトへPictureBoxの画像を格納し、最後にByte配列に値を代入しています。

'// PictureBoxの画像情報をByte配列に保存
Dim byteImage(0) As Byte
If Not PictureBoxProduct.Image Is Nothing Then
     Dim ms As New MemoryStream
     PictureBoxProduct.Image.Save(ms, ImageFormat.Jpeg)
     ReDim byteImage(ms.Length)
     ms.Position = 0
     ms.Read(byteImage, 0, Convert.ToInt32(ms.Length))
End If

2.   Byte配列の情報をXML Webサービスへ送信
XML WebサービスへByte配列として値を渡します。

<ソース fmProduct.vb - GetProductDataメソッド>
Dim wSvc As New ws_sman.ServiceStockManagement
Try
     wSvc.UpdateProductData(TextBoxProductCode.Text, _
           TextBoxProductName.Text, _
           CInt(TextBoxPrice.Text), _
           CInt(TextBoxStockNum.Text), _
           TextBoxUnit.Text, _
           TextBoxRemarks.Text, _
           TextBoxSupplierCode.Text, _
           CInt(TextBoxPurchasePrice.Text), _
           CInt(TextBoxOrderPoint.Text), _
           byteImage)

3.   Byte配列からBLOBフィールドへの格納
XML Webサービス側で受け取った画像情報(Byte配列)はOracleParameterオブジェクトを使用し、BLOBフィールドへ値を渡します。

<ソース ServiceStockManager.asmx.vb - UpdateProductDataメソッド>

Byte配列(byteImage)で画像情報をパラメータで取得後、

prm(9) = cmd.Parameters.Add("productimage", byteImage)

とパラメータでBLOBフィールドであるProductImageフィールドへByte配列を渡しています。


 XMLの扱い

今回のサンプルでは、受注明細データをXML形式にて格納しています。XMLTypeフィールドを使用し、DataSetオブジェクトの内容をXMLに変換後に格納しております。実際のXMLフィールドへの更新は以下のようになります。

  XMLTypeフィールドの更新

XMLTypeフィールドの更新はSQL文に直接XMLを記述するか、もしくはXMLTypeとしてパラメータを渡して更新する方法があります。XMLデータは通常長文になると思われるので、以下のサンプルコードではパラメータ渡しをしております。

<ソース ServiceStockManager.asmx.vb - UpdateOrderDataメソッド>

DataSetはWriteXmlメソッドにより内容をそのままXMLに変換できます。上記のサンプルではDataSetからXMLに変換後、その値をXMLTypeフィールドへ格納しております。

Dim sw As New IO.StringWriter
XmlData.WriteXml(sw)
prm(4) = cmd.Parameters.Add("orderxml", OracleDbType.XmlType)
prm(4).Value = sw.ToString


  XMLTypeフィールドからのデータ取得

XML TypeフィールドからのDataSetオブジェクトへデータの取得は以下のソースコードのように特に特別なコーディングは要りません。

<ソース ServiceStockManager.asmx.vb - GetOrderDataメソッド>

DataSetオブジェクトに取得したXMLデータは以下のようにDataSetオブジェクトに変換できます。

Dim sr As IO.StringReader = _
     New IO.StringReader(dsData.Tables("OrderData").Rows(0).Item("OrderXml"))
dsOrderData.Clear()
dsOrderData.ReadXml(sr)

上記のサンプルコードでは DataSetオブジェクトのReadXmlを使用し、XMLデータをDataSetオブジェクトに格納しております。


  XMLTypeフィールドの操作

XMLTypeフィールドの操作は、以下のようなコードになります。サンプル・アプリケーションでは、発注データの挿入トリガで商品マスタの在庫数更新をしております。



 トランザクション

ODP.NETではローカルトランザクション処理としてOracleTransactionクラスを用意しております。今回のサンプルアプリケーションでは、Oracleへの接続はXML Webサービスを使用しているので、トランザクション制御もXML Webサービス上で行っています。以下の手順でXML Webサービスでのトランザクション制御を実装します。
  1. System.EnterpriseServicesの参照設定。
  2. WebMethod 属性の変更。

ポイント:XML Webサービス上で分散トランザクションを利用するために、Oracle Services For Microsoft Transaction Serverがインストールされている必要があります。


  System.EnterpriseServicesの参照設定

Webサービス側のプロジェクト(WebServiceStockManagement)上で参照の追加を以下の手順で行います。



  WebMethod属性の変更

XML Webサービス メソッドの宣言部分にトランザクション制御の設定をします。

<ソース ServiceStockManager.asmx.vb - DeleteCustomerDataメソッド>

WebMethod属性のTransactionOption プロパティをTransactionOption.RequiresNewに設定します。

<WebMethod(TransactionOption:=TransactionOption.RequiresNew)> _

TransactionOptionプロパティには以下の種類があります。

項目 説明
Disabled XML Webサービス メソッドが、トランザクションのスコープ内で実行されないことを示します。要求が処理されるときに、XML Webサービス メソッドがトランザクションなしで実行されます。[WebMethod(TransactionOption= TransactionOption.Disabled)]
NotSupported XML Webサービス メソッドが、トランザクションのスコープ内で実行されないことを示します。要求が処理されるときに、XML Webサービス メソッドがトランザクションなしで実行されます。[WebMethod(TransactionOption= TransactionOption.NotSupported)]
Supported XML Webサービス メソッドが、トランザクションのスコープ内で実行されないことを示します。要求が処理されるときに、XML Webサービスがトランザクションなしで作成されます。[WebMethod(TransactionOption= TransactionOption.Supported)]
Required XML Webサービス メソッドに、トランザクションが必要であることを示します。XML Webサービス メソッドは、トランザクションにルート オブジェクトとしてだけ参加できるため、XML Webサービス メソッド用に新しいトランザクションが作成されます。[WebMethod(TransactionOption= TransactionOption.Required)]
RequiresNew XML Webサービス メソッドに新しいトランザクションが必要であることを示します。要求が処理されるときに、新しいトランザクション内で XML Webサービスが作成されます。[WebMethod(TransactionOption= TransactionOption.RequiresNew)]

XML Webサービス メソッドから例外がスローされるか、XML Webサービス メソッドによって例外がキャッチされない場合、トランザクションは自動的に中止されます。例外が発生しない場合、このメソッドが SetAbort を明示的に呼び出さない限り、トランザクションは自動的にコミットされます。