ヘッダーをスキップ
Oracle® Data Provider for .NET開発者ガイド
11g リリース2 (11.2.0.4)
B66456-02
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

OracleDataReaderオブジェクトからのデータの取得

OracleCommandオブジェクトのExecuteReaderメソッドは、OracleDataReaderオブジェクトを戻します。このオブジェクトは、読取り専用および順方向専用の結果セットです。

この項では、OracleDataReaderオブジェクトに関する次の情報を示します。

OracleDataReader型指定アクセッサ

OracleDataReaderクラスは、2つのタイプの型指定アクセッサを提供します。

.NETタイプのアクセッサ

表3-12には、ODP.NETがサポートするすべてのOracleデータベースのネイティブ・タイプと、それらに対応した、Oracleネイティブ・タイプを表す.NETタイプがリストされています。Oracleネイティブ・タイプを表すために複数の.NETタイプが使用される場合、最初の.NETタイプ・エントリは、Oracleネイティブ・タイプを最も適切に表します。3列目は、.NETタイプとして取得されるOracleネイティブ・タイプに対して起動される有効な型指定アクセッサを示します。無効な型指定アクセッサが列に使用された場合、InvalidCastExceptionがスローされます。Oracleネイティブ・データ型は、データベースのバージョンに依存します。このため、Oracle Databaseの以前のバージョンでは使用できないデータ型もあります。

表3-12 .NETタイプのアクセッサ

Oracleネイティブ・データ型 .NETタイプ 型指定アクセッサ

BFILE

System.Byte[]

GetBytes

BINARY_DOUBLE

System.Double

GetDouble

BINARY_FLOAT

System.Single

GetFloat

BLOB

System.Byte[]

GetBytes

CHAR

System.String

System.Char[]

GetString

GetChars

CLOB

System.String

System.Char[]

GetString

GetChars

DATE

System.DateTime

GetDateTime

INTERVAL DAY TO SECOND

System.Timespan

GetTimeSpan

INTERVAL YEAR TO MONTH

System.Int64

GetInt64

LONG

System.String

System.Char[]

GetString

GetChars

LONG RAW

System.Byte[]

GetBytes

NCHAR

System.String

System.Char[]

GetString

GetChars

NCLOB

System.String

System.Char[]

GetString

GetChars

NUMBER

System.Decimal

System.Byte

System.Int16

System.Int32

System.Int64

System.Single

System.Double

GetDecimal

GetByte

GetInt16

GetInt32

GetInt64

GetFloat

GetDouble

NVARCHAR2

System.String

System.Char[]

GetString

GetChars

RAW

System.Byte[]

GetBytes

REF

System.String

GetString

ROWID

System.String

System.Char[]

GetString

GetChars

TIMESTAMP

System.DateTime

GetDateTime

TIMESTAMP WITH LOCAL TIME ZONE

System.DateTime

GetDateTime

TIMESTAMP WITH TIME ZONE

System.DateTime

GetDateTime

UROWID

System.String

System.Char[]

GetString

GetChars

VARCHAR2

System.String

System.Char[]

GetString

GetChars

XMLType

System.String

System.Xml.XmlReader

GetString

GetXmlReader


OracleDataReaderオブジェクトの一部のメソッドおよびプロパティでは、列の精度とスケールに基づいて、ODP.NETでNUMBER列を.NETタイプにマップする必要があります。これらのメンバーは、次のとおりです。

  • Itemプロパティ

  • GetFieldTypeメソッド

  • GetValueメソッド

  • GetValuesメソッド

ODP.NETは、次の.NETタイプを順に検証して、列の値の範囲全体を表すリストの最初の.NETタイプを選択することで、適切な.NETタイプを決定します。

  • System.Byte

  • System.Int16

  • System.Int32

  • System.Int64

  • System.Single

  • System.Double

  • System.Decimal

列の値の範囲全体を表す.NETタイプが存在しない場合、列値をSystem.Decimalタイプとして表そうとします。列の値をSystem.Decimalとして表せない場合、例外が発生します。

たとえば、2つの列をNUMBER(4,0)およびNUMBER(10,2)として定義してみます。列の値の範囲全体を表す前のリストでは、最初の.NETタイプはそれぞれSystem.Int16System.Doubleです。次に、列をNUMBER(20,10)として定義してみます。この場合、列の値の範囲全体を表す.NETタイプが存在しないため、列の値をSystem.Decimalタイプとして戻そうとします。列の値をSystem.Decimalタイプとして表せない場合、例外が発生します。

OracleDataAdapterFillメソッドは、OracleDataReaderオブジェクトを使用して、.NETタイプのDataTableまたはDataSetを移入あるいはリフレッシュします。その結果、DataTableまたはDataSetNUMBER列を表すために使用される.NETタイプも、その列の精度とスケールに依存します。

ODP.NETタイプのアクセッサ

ODP.NETは、データベースのデータ型をネイティブに表すプロバイダ固有のタイプを公開します。これらのODP.NETタイプにより、対応する.NETタイプよりもパフォーマンスおよび機能性が上回る機能が提供される場合があります。ODP.NETタイプは、それぞれの型指定アクセッサをコールすることで、OracleDataReaderオブジェクトから取得できます。


関連項目:

すべてのODP.NETタイプのリストは、「ODP.NETタイプの概要」を参照してください。

表3-13には、ODP.NETがOracleネイティブ・タイプのODP.NETタイプを取得する際に使用する有効なタイプのアクセッサがリストされています。

表3-13 ODP.NETタイプのアクセッサ

Oracleネイティブ・データ型 ODP.NETタイプ 型指定アクセッサ

BFILE

OracleBFile

GetOracleBFile

BINARY_DOUBLE

OracleDecimal

GetOracleDecimal

BINARY_FLOAT

OracleDecimal

GetOracleDecimal

BLOB

OracleBlob

OracleBlob

OracleBinary

GetOracleBlob

GetOracleBlobForUpdate

GetOracleBinary

CHAR

OracleString

GetOracleString

CLOB

OracleClob

OracleClob

OracleString

GetOracleClob

GetOracleClobForUpdate

GetOracleString

DATE

OracleDate

GetOracleDate

INTERVAL DAY TO SECOND

OracleIntervalDS

GetOracleIntervalDS

INTERVAL YEAR TO MONTH

OracleIntervalYM

GetOracleIntervalYM

LONG

OracleString

GetOracleString

LONG RAW

OracleBinary

GetOracleBinary

NCHAR

OracleString

GetOracleString

NCLOB

OracleString

GetOracleString

NUMBER

OracleDecimal

GetOracleDecimal

NVARCHAR2

OracleString

GetOracleString

RAW

OracleBinary

GetOracleBinary

REF

OracleRef

GetOracleRef

ROWID

OracleString

GetOracleString

TIMESTAMP

OracleTimeStamp

GetOracleTimeStamp

TIMESTAMP WITH LOCAL TIME ZONE

OracleTimeStampLTZ

GetOracleTimeStampLTZ

TIMESTAMP WITH TIME ZONE

OracleTimeStampTZ

GetOracleTimeStampTZ

UROWID

OracleString

GetOracleString

VARCHAR2

OracleString

GetOracleString

XMLType

OracleString

OracleXmlType

GetOracleString

GetOracleXmlType


LONGおよびLONG RAWデータの取得

ODP.NETは、OracleDataReaderオブジェクトでReadメソッドを起動中に、データベースから行をフェッチおよびキャッシュします。この操作により取得されるLONGおよびLONG RAW列データの量は、InitialLONGFetchSizeにより決定されます。InitialLONGFetchSizeが、00より大きな値および-1に設定されている場合の動作の違いは、次の各項で説明します。


注意:

ODP.NETでは、CommandBehavior.SequentialAccess列挙値はサポートされていません。このため、LONGおよびLONG RAWデータはランダムにフェッチできます。

InitialLONGFetchSizeを0(ゼロ)または0(ゼロ)より大きな値に設定

OracleDataReaderオブジェクトでReadメソッドを起動中に、LONGまたはLONG RAW列データに対して指定された、InitialLONGFetchSizeの文字数またはバイト数がキャッシュに取り出されます。

デフォルトでは、InitialLONGFetchSizeは0に設定されています。この場合ODP.NETは、OracleDataReader オブジェクト上でのReadメソッドの起動中、LONGまたはLONG RAW列データのいずれもフェッチしません。データがキャッシュされないため、データベースのラウンド・トリップの原因となるLONGまたはLONG RAW列に対して型指定アクセッサ・メソッドが明示的に起動されると、LONGまたはLONG RAWデータがフェッチされます。

InitialLONGFetchSize0より大きな値に設定された場合、OracleDataReaderオブジェクトでReadメソッドを起動すると、ODP.NETにより、指定された量のデータがキャッシュされます。アプリケーションが型指定アクセッサ・メソッドによりInitialLONGFetchSize以下のデータ量を要求した場合、データベース・ラウンドトリップは発生しません。ただし、InitialLONGFetchSizeを超えるデータをフェッチするには、追加のデータベース・ラウンドトリップが必要です。

InitialLONGFetchSize文字数またはバイト数よりも多くのデータを取得するには、選択リストに次のいずれかが必要です。

  • 主キー

  • ROWID

  • 一意の列 - (一意制約が定義されたか、または一意索引が作成された1セットの列として定義されたもの。セット内の少なくとも1列には、ここで定義されたNOT NULL制約があります)

選択リストに主キー列(ROWID)または一意の列がない状態で、LONGまたはLONG RAWデータ全体をフェッチするには、OracleCommandオブジェクトのInitialLONGFetchSizeプロパティのサイズを、検索に必要な文字数またはバイト数以上に設定します。

OracleDataReaderオブジェクトで適切な型指定アクセッサ・メソッド(LONGの場合GetCharsGetOracleStringまたはGetStringLONG RAWの場合GetOracleBinaryまたはGetBytes)がコールされたときに、LONGまたはLONG RAWデータが戻されます。

InitialLONGFetchSizeを-1に設定

InitialLONGFetchSize-1に設定すると、選択リストに主キー、ROWIDまたは一意の列を必要とせずに、SELECT問合せに対してデータベースからLONGまたはLONG RAWデータ全体をフェッチできます。

InitialLONGFetchSize-1に設定されると、OracleDataReaderオブジェクトでReadメソッドを起動中に、LONGまたはLONG RAWデータ全体が取り出され、キャッシュされます。OracleDataReaderオブジェクトでGetStringGetOracleStringGetCharsGetBytesまたはGetOracleBinaryをコールすると、列データ全体が戻されます。

LOBデータの取得

ODP.NETは、OracleDataReaderオブジェクトでReadメソッドを起動中に、データベースから行をフェッチおよびキャッシュします。この操作により取得されるLOB列データの量は、InitialLOBFetchSizeにより決定されます。

次の各項では、InitialLOBFetchSizeが、00より大きな値および-1に設定されている場合の動作の違いを説明します。

InitialLOBFetchSizeを0(ゼロ)に設定

デフォルトで、InitialLOBFetchSizeプロパティを0に設定すると、OracleDataReaderでメソッドGetOracleBlob()GetOracleClob()メソッドが起動され、OracleBlobオブジェクトおよびOracleClobオブジェクトを取得できます。

InitialLOBFetchSizeが0(ゼロ)に設定されている場合、アプリケーションがCLOB列およびBLOB列に対してコールできる型指定アクセッサ・メソッドの全リストを次に示します。

  • BLOB列に対してコールできるメソッド

    • GetBytes

    • GetValue

    • GetValues

    • GetOracleBinary

    • GetOracleBlob

    • GetOracleBlobForUpdate

    • GetOracleValue

    • GetOracleValues

  • CLOB列に対してコールできるメソッド

    • GetChars

    • GetString

    • GetValue

    • GetValues

    • GetOracleString

    • GetOracleClob

    • GetOracleClobForUpdate

    • GetOracleValue

    • GetOracleValues

InitialLOBFetchSizeを0(ゼロ)より大きな値に設定

InitialLOBFetchSize0より大きな値に設定すると、OracleDataReaderオブジェクトに対するReadメソッドを起動中に、ODP.NETにより、選択された各LOBに対してInitialLOBFetchSizeの文字数またはバイト数までのLOBデータがキャッシュされます。

この項では、キャッシュされるInitialLOBFetchSize文字数またはバイト数よりも多くのデータをフェッチする方法について説明します。この機能は、Oracle Database 10gリリース2(10.2)以上では変更されています。

Oracle Database 10gリリース2(10.2)以前での追加データの取得

Oracle Database 10gリリース2(10.2)以前のリリースでは、InitialLOBFetchSize文字数またはバイト数よりも多くのデータを取得するには、問合せ選択リストに次のいずれかが必要です。

  • 主キー

  • ROWID

  • 一意の列 - (一意制約が定義されたか、または一意索引が作成された1セットの列として定義されたもの。セット内の少なくとも1列には、ここで定義されたNOT NULL制約があります)

OracleDataReaderオブジェクトで適切な型指定アクセッサ・メソッドがコールされると、要求されたLOBデータがデータベースからフェッチされます。

選択リストに主キー列(ROWID)または一意の列がない場合、LOBデータ全体をフェッチするには、OracleCommandオブジェクトのInitialLOBFetchSizeプロパティのサイズを、検索に必要な文字数またはバイト数以上に設定します。

InitialLOBFetchSizeプロパティを0(ゼロ)以外の値に設定すると、GetOracleBlobGetOracleClobGetOracleBlobForUpdateおよびGetOracleClobForUpdate型指定アクセッサ・メソッドが無効になります。

Oracle Database 10gリリース2(10.2)以上での追加データの取得

Oracle Database 10gリリース2(10.2)以上では、InitialLOBFetchSizeプロパティに設定された値に関係なく、型指定アクセッサが起動されるとLOBデータ全体が戻されます。指定されたInitialLOBFetchSizeよりも多くのデータを取得するために、主キー、ROWIDまたは一意の列を問合せ選択リストに含める必要はありません。

Oracle Database 10gリリース2以上では、InitialLOBFetchSize0より大きな値であっても、GetOracleBlobGetOracleClobGetOracleBlobForUpdateおよびGetOracleClobForUpdateメソッドを起動できるようになりました。

InitialLOBFetchSize0より大きな値に設定されている場合に、アプリケーションがCLOB列およびBLOB列に対してコールできる型指定アクセッサ・メソッドの全リストを次に示します。

  • BLOB列に対してコールできるメソッド

    • GetBytes

    • GetValue

    • GetValues

    • GetOracleBinary

    • GetOracleBlob

    • GetOracleBlobForUpdate

    • GetOracleValue

    • GetOracleValues

  • CLOB列に対してコールできるメソッド

    • GetChars

    • GetString

    • GetValue

    • GetValues

    • GetOracleString

    • GetOracleClob

    • GetOracleClobForUpdate

    • GetOracleValue

    • GetOracleValues

InitialLOBFetchSizeを-1に設定

InitialLOBFetchSize-1に設定することで、選択リストに主キー、ROWIDまたは一意の列がない場合も、SELECT問合せに対してデータベースからLOBデータ全体をフェッチできます。InitialLOBFetchSize-1に設定されると、OracleDataReaderオブジェクトでReadメソッドを起動中に、LOB列データ全体がフェッチおよびキャッシュされます。OracleDataReaderオブジェクトでGetStringGetOracleStringGetCharsGetBytesまたはGetOracleBinaryをコールすると、すべてのデータを取得できます。

InitialLOBFetchSizeを-1に設定した場合にサポートされるメソッド

この項では、InitialLOBFetchSizeプロパティが-1に設定されている場合に、CLOBおよびBLOBデータ型に対してサポートされているメソッドとサポートされていないメソッドをリストしています。

表3-14では、CLOBデータ型に対してサポートされているメソッドとサポートされていないメソッドをリストしています。

表3-14 OracleDataReader CLOBメソッド

サポート対象 サポート対象外

GetChars

GetOracleClob

GetString

GetOracleClobForUpdate

GetValue


GetValues


GetOracleString


GetOracleValue


GetOracleValues



表3-15では、BLOBデータ型に対してサポートされているメソッドとサポートされていないメソッドをリストしています。

表3-15 OracleDataReader BLOBメソッド

サポート対象 サポート対象外

GetBytes

GetOracleBlob

GetValue

GetOracleBlobForUpdate

GetValues


GetOracleBinary


GetOracleValue


GetOracleValues



InitialLOBFetchSizeプロパティに関連したパフォーマンス上の考慮事項

この項では、異なる状況における、InitialLOBFetchSizeプロパティの様々な設定のメリットおよびデメリットについて説明します。また、使用しているデータベース・リリースに応じたパフォーマンスの強化方法についても説明します。

Oracle Database 10gリリース2(10.2)以前

InitialLOBFetchSizeプロパティをゼロ以外の値に設定すると、パフォーマンスが向上する場合があります。InitialLOBFetchSizeプロパティを使用すると、OracleBlobオブジェクトまたはOracleClobオブジェクトを使用して基礎となるLOBデータを検索するよりもパフォーマンスが向上します。これは、アプリケーションがOracleDataReaderオブジェクトからOracleBlobオブジェクトおよびOracleClobオブジェクトを取得する必要がなく、LOB列データのサイズがあまり大きくない場合に当てはまります。問合せで戻されるLOB列データのサイズがすべての行でほぼ同じ場合、InitialLOBFetchSizeは特に便利です。

通常、InitialLOBFetchSizeプロパティは、問合せで戻される行の80%以上のLOBデータのサイズより大きい値に設定することをお薦めします。たとえば、LOBデータのサイズが行の80%で1KB未満で、行の20%で1MB以上である場合、InitialLOBFetchSizeプロパティを1KBに設定します。

Oracle Database 10gリリース2(10.2)以上

アプリケーションで、パフォーマンスとOracleBlobおよびOracleClob機能のどちらをとるかを選択する必要はありません。InitialLOBFetchSizeプロパティを設定すると、パフォーマンスは向上し、OracleBlobオブジェクトおよびOracleClobオブジェクトを使用する自由度はそのままです。

LOBデータのサイズが不明であったり、LOBデータのサイズが不規則に変化する場合は、InitialLOBFetchSizeプロパティをデフォルト値の0のままにしてください。これでも、ほとんどの場合でパフォーマンスが改善されます。

大部分の行についてInitialLOBFetchSizeプロパティのサイズをLOBデータ・サイズ以上に設定すると、パフォーマンスが劇的に改善されます。通常、InitialLOBFetchSizeプロパティは、問合せで戻される行の80%以上のLOBデータのサイズより大きい値に設定することをお薦めします。たとえば、LOBデータのサイズが行の80%で1KB未満で、行の20%で1MB以上である場合、InitialLOBFetchSizeプロパティを1KBに設定します。

1回のデータベース・ラウンドトリップでフェッチされる行数の制御

アプリケーションのパフォーマンスは、アプリケーションがフェッチする必要のある行数と、行の検索に必要なデータベース・ラウンドトリップの回数に依存します。

FetchSizeの使用

FetchSizeプロパティは、データベース・ラウンドトリップからフェッチされたデータをキャッシュするためにODP.NETが割り当てるメモリー・サイズの合計をバイトで表したものです。

FetchSizeプロパティは、状況に応じてOracleCommandOracleDataReaderまたはOracleRefCursorオブジェクトで設定できます。これは、OracleDataAdapterを使用してDataSetまたはDataTableに移入を行う場合のフェッチ・サイズを制御します。

FetchSizeプロパティをOracleCommandオブジェクトで設定した場合、新しく作成されたOracleDataReaderは、OracleCommandオブジェクトのFetchSizeプロパティを継承します。この継承されたFetchSizeは、そのままにしておくか、継承された値を上書きするように変更できます。OracleDataReaderオブジェクトのFetchSizeプロパティは、最初のReadメソッドを起動する前に変更できます。このメソッドは、FetchSizeプロパティで指定されたメモリーを割り当てます。データベースからの後続のフェッチはすべて、そのOracleDataReaderに割り当てられた同じキャッシュを使用します。このため、最初のReadメソッドを起動した後にFetchSizeを変更しても影響はありません。

FetchSizeの微調整

FetchSizeプロパティを微調整することで、アプリケーションは、メモリー使用率、および1回のデータベース・ラウンドトリップでフェッチされる行数を制御して、パフォーマンスを向上させることができます。

たとえば、問合せが100行を戻し、各行が1024バイトある場合、FetchSizeプロパティを102400に設定すると、1回のデータベース・ラウンドトリップで100行をフェッチできます。同じ問合せで、FetchSizeプロパティを10240に設定すると、100行を検索するのに10回のデータベース・ラウンドトリップが必要になります。アプリケーションが結果セットからすべての行をフェッチする必要がある場合、最初の使用例の方が2番目の使用例より高速になります。ただし、アプリケーションが結果セットから最初の10行のみをフェッチする必要がある場合、100行ではなく10行のみをフェッチするため、2番目の使用例の方がパフォーマンスが向上します。次の10行をフェッチする場合、行1から10に割り当てられたメモリーが行11から20で再び使用されます。

FetchSizeが大きいほど、より多くのシステム・メモリーが使用されます。クライアント・システムのメモリー・リソースに制限がある場合、開発者は大きなフェッチ・サイズを設定できません。

RowSizeプロパティの使用

OracleCommandまたはOracleRefCursorオブジェクトのRowSizeプロパティには、SELECT文の実行後に行サイズ(バイト)が移入されます。FetchSizeプロパティは、RowSize値とデータベース・ラウンドトリップごとにフェッチされる行数の積に設定することで、RowSizeプロパティに応じた値に設定できます。

たとえば、FetchSizeRowSize * 10に設定すると、OracleDataReaderオブジェクトでは、データベース・ラウンドトリップごとに10行のみが強制的にフェッチされます。各列のデータ長によってRowSizeが変わることはありません。RowSizeは、SELECT文が実行されるデータベース表のメタデータ情報から正確に決定されます。

RowSizeプロパティを使用すると、次の項で説明するように、設計時または実行時にFetchSizeプロパティを設定できます。

レジストリ内のFetchSize値の設定

HKLM\Software\Oracle\ODP.NET\version\FetchSizeレジストリ・エントリは、特定のバージョンのODP.NETを使用するすべてのアプリケーションに対するデフォルトの結果セットのフェッチ・サイズをバイト単位で指定するように設定できます。または、アプリケーション構成ファイルまたはweb.configファイルのFetchSize属性で、特定のアプリケーションに対するデフォルト値を指定できます。デフォルトのフェッチ・サイズは131072バイトです。この値は、実行時にアプリケーションのFetchSizeプロパティをOracleCommandまたはOracleDataReaderに対してプログラムで設定することによって無視できます。

設計時のFetchSize値の設定

特定のSELECT文の行サイズが前の実行ですでにわかっている場合、OracleCommandオブジェクトのFetchSize値は、設計時に、その行サイズとアプリケーションがデータベース・ラウンドトリップごとにフェッチする必要がある行数の積に設定できます。OracleCommandオブジェクトのFetchSize値セットは、OracleCommandオブジェクトでExecuteReaderメソッドを起動したときに作成されたOracleDataReaderオブジェクトにより継承されます。OracleCommandオブジェクトでFetchSizeを設定するのではなく、OracleDataReaderで直接FetchSizeを設定することもできます。いずれの場合にも、実行時にRowSizeプロパティ値にアクセスしなくても、FetchSizeは設計時に設定されます。

実行時のFetchSize値の設定

設計時に行サイズがわからないアプリケーションでは、OracleCommandオブジェクトのRowSizeプロパティを使用して、OracleDataReaderオブジェクトのFetchSizeプロパティを設定できます。RowSizeプロパティは、行のサイズに基づいて、動的な方法でFetchSizeプロパティを設定します。

OracleCommandオブジェクトでExecuteReaderメソッドを起動してOracleDataReaderオブジェクトを取得した後に、RowSizeプロパティが行のサイズ(バイト)とともに移入されます。RowSizeプロパティを使用することで、アプリケーションは、OracleDataReaderオブジェクトのFetchSizeプロパティを、RowSizeプロパティ値とアプリケーションがデータベース・ラウンドトリップごとにフェッチする必要がある行数の積に動的に設定できます。この使用例では、実行時にRowSizeプロパティにアクセスすることでFetchSizeが設定されます。