連載
» 2005年01月27日 00時00分 公開

ODP.NETファーストステップ(3):ODP.NETのデータアクセス・チューニング (1/4)

Windowsプラットフォームにおけるアプリケーション開発は、.NETが主流となりつつある。本連載はVisual Basicから.NETへの移行を考えているOracleアプリケーション開発者に向けて、「Oracle Data Provider for .NET」を使うメリットや独自機能、新しいプログラミング・スタイルなどを解説する。(編集局)

[大田浩,日本オラクル]

主な内容

--Page 1--

▼LOBデータの操作とチューニング

▼BLOBアクセスの基本操作

▼LOBデータ取得時のパフォーマンス・チューニング

--Page 2--

OracleDataReader使用時のパフォーマンス・チューニング

ODP.NETからPL/SQLを利用

ストアドプロシージャの呼び出し方法

ストアドファンクションから戻り値を取得する方法

--Page 3--

PL/SQL配列を利用する方法

--Page 4--

非接続型でのデータアクセスの注意点


 今回はOracle Data Provider for .NET(以下、ODP.NET)を利用してOracleデータベースへアクセスするための詳細な説明と、パフォーマンスを向上させるためのコーディング・テクニックについて説明します。

LOBデータの操作とチューニング

 LOBとはラージオブジェクト(Large Object)のことで、ギガバイト級の大きなファイルサイズのデータを扱うオブジェクトです。LOBのデータ型は主にBLOB(Binary Large Object)とCLOB(Character Large Object)の2種類に分類されます。

BLOBアクセスの基本操作

 まず、ODP.NETからBLOBへのアクセス方法を説明します。

手順1

 テスト用のBLOBフィールドを含んだテーブルを作成します。

create table blob_test(
  blob_id  number(4,0) primary key,
  blob_fld blob
);

手順2

 以下のサンプル用ビットマップ・イメージファイルをダウンロードして、Cドライブのtempディレクトリに保存してください。

手順3

 BLOBフィールドへの値の代入は、以下のようなコードになります。

Dim fs As New System.IO.FileStream("c:\temp\odp.bmp", _
  IO.FileMode.Open, IO.FileAccess.Read)
Dim blobData(fs.Length) As Byte
fs.Read(blobData, 0, fs.Length)
Dim cnn As New OracleConnection( _
  "user id=scott;password=tiger;data source=orcl")
Dim strSql As String = _
  "insert into blob_test(blob_id, blob_fld) " & _
  "values(1, :blobdata)"
Dim cmd As New OracleCommand(strSql, cnn)
cnn.Open()
Dim pBlob As OracleParameter = _
  cmd.Parameters.Add("blobdata", OracleDbType.Blob)
pBlob.Value = blobData
cmd.ExecuteNonQuery()
リスト1 BLOBフィールドへファイルを挿入するサンプルコード(VB.NET)

System.IO.FileStream fs = 
  new System.IO.FileStream("c:\\temp\\odp.bmp", 
  System.IO.FileMode.Open, System.IO.FileAccess.Read);
byte[] blobData = new byte[fs.Length];
fs.Read(blobData, 0,(int)fs.Length);
OracleConnection cnn = 
  new OracleConnection(
  "user id=scott;password=tiger;data source=orcl");
String strSql = 
  "insert into blob_test(blob_id, blob_fld) " +
  "values(1, :blobdata)";
OracleCommand cmd = new OracleCommand(strSql, cnn);
cnn.Open();
OracleParameter pBlob = 
  cmd.Parameters.Add("blobdata", OracleDbType.Blob);
pBlob.Value = blobData;
cmd.ExecuteNonQuery();
リスト2 BLOBフィールドへファイルを挿入するサンプルコード(C#)

 OracleParameterオブジェクトのOracleDbTypeプロパティをBlobに指定し、画像データなどのバイナリデータを格納します。

注意:今回のサンプルコードはすべて、ODP.NETの名前空間の指定(Oracle.DataAccess.ClientとOracle.DataAccess.Types)を省略して記述してあります。

手順4

 BLOBフィールドから値を取得し、PictureBoxに表示するコードは以下になります。

Dim cnn As New OracleConnection( _
  "user id=scott;password=tiger;data source=orcl")
Dim strSql As String = _
  "select blob_fld from blob_test where blob_id=1"
Dim cmd As New OracleCommand(strSql, cnn)

cnn.Open()
Dim dr As OracleDataReader = cmd.ExecuteReader
If dr.Read Then
  Dim blob As OracleBlob = dr.GetOracleBlob(0)
  Dim ms As New System.IO.MemoryStream(blob.Value)
  PictureBox1.Image = New Bitmap(ms)
End If
リスト3 BLOBフィールドに格納された画像データをPictureBoxに表示するサンプルコード(VB.NET)

OracleConnection cnn = 
  new OracleConnection(
    "user id=scott;password=tiger;data source=orcl");
String strSql = 
  "select blob_fld from blob_test where blob_id=1";
OracleCommand cmd = new OracleCommand(strSql, cnn);

cnn.Open();
OracleDataReader dr = cmd.ExecuteReader();
if(dr.Read())
{
  OracleBlob blob = dr.GetOracleBlob(0);
  System.IO.MemoryStream ms =
    new System.IO.MemoryStream(blob.Value);
  pictureBox1.Image = new Bitmap(ms);
}
リスト4 BLOBフィールドに格納された画像データをPictureBoxに表示するサンプルコード(C#)

 BLOB型で格納された情報を取得するには、OracleDataReaderオブジェクトのGetOracleBlobメソッドを使用し、結果をOracleBlobオブジェクトに格納します。

LOBデータ取得時のパフォーマンス・チューニング

 LOBの列型を含むOracleDataReaderが作成されると、OracleDataReaderを作成したOracleCommandのInitialLOBFetchSizeプロパティの値がOracleDataReaderによってチェックされ、LOBの列データをすぐにフェッチする必要があるかどうかが判断されます。デフォルトでは、InitialLOBFetchSizeは「0」に設定されています。

 OracleCommandのInitialLOBFetchSizeプロパティの値が「0」のままであれば、LOBデータ全体の取得は、アプリケーションによってデータが明示的に要求されるまで延期されます。InitialLOBFetchSizeプロパティが「0」以外の値に設定されていると、その値の文字数またはbyte数までLOBデータが即座にフェッチされます。

 InitialLOBFetchSizeプロパティがデフォルトの「0」の場合、OracleDataReaderのGetOracleBlob/GetOracleClobメソッドを起動して、OracleBlob/OracleClobオブジェクトを取得できます。ただしInitialLOBFetchSizeが「0」以外の値に設定されていると、GetOracleBlob/GetOracleClobメソッドは無効です。その場合には、GetBytes/GetCharsメソッドをそれぞれ使用してBLOB/CLOBデータをフェッチする必要があります。InitialLOBFetchSizeを指定したコードは以下のようになります。

Dim cnn As New OracleConnection( _
  "user id=scott;password=tiger;data source=orcl")
Dim strSql As String = _
  "select blob_fld from blob_test where blob_id=1"
Dim cmd As New OracleCommand(strSql, cnn)

cnn.Open()
cmd.InitialLOBFetchSize = 32767
Dim dr As OracleDataReader = cmd.ExecuteReader
If dr.Read Then
  Dim byteArray(32767) As Byte
  Dim numBytesRead As Long = _
    dr.GetBytes(0, 0, byteArray, 0, 32767)
  Dim ms As New System.IO.MemoryStream(byteArray)
  PictureBox1.Image = New Bitmap(ms)
End If
リスト5 InitialLOBFetchSizeを指定して、BLOBフィールドに格納された画像データをPictureBoxに表示するサンプルコード(VB.NET)

OracleConnection cnn = 
  new OracleConnection(
    "user id=scott;password=tiger;data source=orcl");
String strSql = 
  "select blob_fld from blob_test where blob_id=1";
OracleCommand cmd = new OracleCommand(strSql, cnn);

cnn.Open();
cmd.InitialLOBFetchSize = 32767;
OracleDataReader dr = cmd.ExecuteReader();
if(dr.Read())
{
  byte [] byteArray = new byte[32767];
  long numBytesRead = 
    dr.GetBytes(0, 0, byteArray, 0, 32767);
  System.IO.MemoryStream ms = 
    new System.IO.MemoryStream(byteArray);
  pictureBox1.Image = new Bitmap(ms);
}
リスト6 InitialLOBFetchSizeを指定して、BLOBフィールドに格納された画像データをPictureBoxに表示するサンプルコード(C#)

 InitialLOBFetchSizeを「0」以外の値に設定すると、OracleBlob/OracleClobオブジェクトを使用してLOBデータを取得するよりも、高いパフォーマンスを得られることがあります。OracleDataReaderからOracleBlob/OracleClobオブジェクトを取得する必要のないアプリケーションで、LOB列データがそれほど大きくない場合がこれに該当します。InitialLOBFetchSizeは、問い合わせで返されるLOB列データのサイズがすべての行でほぼ同じ場合、特に便利です。

 一般にInitialLOBFetchSizeは、問い合わせで返される行のうち、80%を超える行のLOBデータのサイズよりも大きな値に設定することをお勧めします。例えば、80%の行でLOBデータのサイズが1Kbytesよりも小さく、20%の行で1Mbytesよりも大きい場合には、InitialLOBFetchSizeを1Kbytesに設定します。(次ページへ続く)

       1|2|3|4 次のページへ

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。