SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

MonoでDBMS用データプロバイダを使う

Monoで他のDBも使ってみたよ!(SQL Server、Oracle編)

MonoでSQL Server、Oracleを使う

ダウンロード 修正サンプル (125.0 KB)

7.Oracle編

 Oracle用データプロバイダ「System.Data.OracleClient」を使用したDBアクセスについて解説を行います。OracleについてはWikipediaなどを参照してください。

 「System.Data.OracleClient」は「OCI(Oracle call-level interface)」を必要とします。Oracle 8i、9i、10g、11g に対応しています。

補足説明

 「OCI(Oracle call-level interface)」は、Oracle DBのデータを操作するために使用するCライブラリ関数です。詳細についてはOracle Technology Networkを参照して下さい。

セットアップ

 ホストOS側で動作確認用Oracle DBを作成します。ゲストOS側でOracle用データプロバイダ「System.Data.OracleClient」の準備を行います。

 「Oracle Database 10g Express Edition」はOracle Technology NetworkからWindows用のリンクを選択し、「Oracle Database 10g Express Edition (Universal)」(OracleXEUniv.exe)をダウンロードし、インストールを行います。本稿ではインストール自体の解説は割愛します。

 「System.Data.OracleClient」は、Mono 1.9.1のソース(mono-1.9.1.tar.bz2)をNovell社のサイトからダウンロードし、その中に含まれる「System.Data.OracleClient」のソースコードを修正し、ビルドします。詳細についてはデータプロバイダで解説します。

 「OCI(Oracle call-level interface)」については、Oracle Technology NetworkからLinux用のリンクを選択し、「Oracle Database 10g Express Client」(oracle-xe-client-10.2.0.1-1.0.i386.rpm)をダウンロードして、インストールすることで対応します。

Oracle DB

 動作確認用DB(TESTDATA.PRODUCTS)を作成します。sqlplusユーティリティを使用したDB操作を行います。

テーブル作成用SQLファイルの準備

 「D:\Dev\Oracle\sql」(任意)に以下のテーブル作成用SQLファイルを用意します。

Products.sql
--sqlplus testdata/password @Products.sql
--
-- Products テーブル削除
--DROP TABLE Products;

-- Products テーブル作成
CREATE TABLE Products (
  ProductID NUMBER(5) NOT NULL,
  ProductName NVARCHAR2(25) NOT NULL,
  Price NUMBER(7, 2),
  ProductDescription NVARCHAR2(128) NULL);

-- Products テーブル プライマリキー作成
ALTER TABLE Products ADD CONSTRAINT Products_PK PRIMARY KEY (ProductID);

-- INSERT 実行
INSERT INTO Products (ProductID, ProductName, Price, ProductDescription)
  VALUES (0, 'Oracle', NULL, 'Oracle Database 10g Express Edition');

-- INSERT 実行
INSERT INTO Products (ProductID, ProductName, Price, ProductDescription)
  VALUES (1, 'Clamp', 12.48, 'Workbench clamp');

-- INSERT 実行 カラムの順番を変えたパターン
INSERT INTO Products (ProductName, ProductID, Price, ProductDescription)
  VALUES ('Screwdriver', 50, 3.17, 'Flat head');

-- INSERT 実行 カラムリスト指定なし、入力値リストはカラム順パターン
INSERT INTO Products
  VALUES (75, 'Tire Bar', NULL, 'Tool for changing tires.');

-- INSERT 実行 ProductDescription カラムの指定なしパターン
INSERT INTO Products (ProductID, ProductName, Price)
  VALUES (3000, '3mm Bracket', .52);

-- UPDATE 実行
UPDATE Products
  SET ProductName = 'Flat Head Screwdriver'
  WHERE ProductID = 50;

-- SELECT 実行 確認用
SELECT *
  FROM Products;

-- 終了
EXIT
Oracleデータベースの起動

 Oracleデータベースを起動するには、[スタート]-[すべてのプログラム]-[Oracle Database 10g Express Edition]-[データベースの起動](停止は[データベースの停止])を選択します。

ユーザ作成
> sqlplus system/password
SQL> create user testdata
  2  identified by password
  3  default tablespace users
  4  temporary tablespace temp;
権限の付与

 ユーザーに権限(例:ロール(CONNECT,RESOURCE))の付与を行います。

> sqlplus system/password
SQL> grant connect,resource to testdata;
テーブル作成
> D:
> cd Dev\Oracle\sql
> sqlplus testdata/password @Products.sql

データプロバイダ

 Mono 1.9.1から提供されている「mono-data-oracle」パッケージに含まれる「System.Data.OracleClient」にはデータプロバイダファクトリ対応クラス「OracleClientFactory」が実装されていません。「machine.config(2.0 profile)」には標準で「System.Data.OracleClient」のデータプロバイダファクトリ情報が登録されているので、肩透かしをくらったような感じがしましたが、とりあえず対応方法があったので、深く考えないことにします。

「System.Data.OracleClient」への修正

 「System.Data.OracleClient」のソースコードの修正、ビルドについて 、Novell's Bugzillaに、関連すると思われる情報があったので参考にしました(Bug #365911)。

 修正内容については、Mono Anonymous SVN Repositoriesに存在するbranchesおよびtrunk内の「System.Data.OracleClient」配下のソース資源を参考にしました(注:実際に作業を行ったのは、2008年8月上旬で、その時点でのソース資源を参考にしました)。

 ダウンロードしたMono 1.9.1ソース資源内の「System.Data.OracleClient」配下のソース資源に、「OracleClientFactory.cs」の追加、以下の既存資源への修正対応を行います。

修正対象
「~/tmp」 配下に「mono-1.9.1.tar.bz2」を展開する場合:
> cd ~/tmp
> tar xjvf mono-1.9.1.tar.bz2

~/tmp/mono-1.9.1/mcs/class/System.Data.OracleClient 配下
  System.Data.OracleClient.dll.sources:修正
  System.Data.OracleClient/OracleClientFactory.cs:追加
  System.Data.OracleClient/OracleConnection.cs:修正
  System.Data.OracleClient/OracleCommand.cs:修正
  System.Data.OracleClient/OracleDataReader.cs:修正
  System.Data.OracleClient/OracleParameter.cs:修正
  System.Data.OracleClient/OracleParameterCollection.cs:修正
OracleConnection.cs 修正例
440行目
  #if NET_2_0
  [MonoTODO]
  protected override Common.DbTransaction BeginDbTransaction (IsolationLevel level)
  {
    return null;
  }

  [MonoTODO]
  protected override Common.DbCommand CreateDbCommand ()
  {
    return null;
  }	
  #endif
変更
  #if NET_2_0
  [MonoTODO]
  protected override Common.DbTransaction BeginDbTransaction (IsolationLevel level)
  {
    //return null;
    return (Common.DbTransaction)BeginTransaction (level);
  }
	
  [MonoTODO]
  protected override Common.DbCommand CreateDbCommand ()
  {
    //return null;
    return CreateCommand ();
  }
  #endif

 また、SQL文字列内にパラメータを使用して、パラメータに日本語のようなマルチバイト文字を含む文字列をバインドした場合、以下の例外が発生するので、

ORA-01480: STRバインド値に終了のNULLがありません。

 原因箇所のある「OracleParameter.cs」に以下の修正を行う必要があります。

OracleParameter.cs 例外対応
523行目
  bindSize = svalue.Length;
変更
  bindSize = bytes.Length;

 修正対応後、Mono 1.9.1自体のビルドを行います。

ビルド実行例
> cd ~/tmp/mono-1.9.1
> ./configure
> make PROFILE=net_2_0

 ビルド後、「System.Data.OracleClient」をGACへ登録(もしくはMONO_PATHによる配置)を行います。

GACへ登録
> cd ~/tmp/mono-1.9.1/mcs/class/lib/net_2_0
> su
# gacutil -i System.Data.OracleClient.dll -package 2.0
Package exported to: /usr/lib/mono/2.0/System.Data.OracleClient.dll -> ../gac/System.Data.OracleClient/2.0.0.0__b77a5c561934e089/System.Data.OracleClient.dll
Installed System.Data.OracleClient.dll into the gac (/usr/lib/mono/gac)

 また、「Oracle Database 10g Express Client」インストール後、環境変数設定を行う必要があります。以下の設定を「~/.profile」等に追加します。

環境変数設定例
#ADD for Setting the Oracle Database XE Client Environment Variables
. /usr/lib/oracle/xe/app/oracle/product/10.2.0/client/bin/oracle_env.sh

 なお、今回使用した「System.Data.OracleClient」の修正済み修正対象ファイル、アセンブリ「System.Data.OracleClient.dll」をサンプルとして本稿に添付しました

次のページ
8.まとめ

この記事は参考になりましたか?

MonoでDBMS用データプロバイダを使う連載記事一覧

もっと読む

この記事の著者

sta(エステーエー)

風来坊blog:sta.blockhead

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/2920 2008/12/24 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー