OracleCommand
オブジェクトのExecuteReader
メソッドは、OracleDataReader
オブジェクトを戻します。このオブジェクトは、読取り専用および順方向専用の結果セットです。
この項では、OracleDataReader
オブジェクトに関する次の情報を示します。
OracleDataReader
クラスは、2つのタイプの型指定アクセッサを提供します。
表3-11には、ODP.NETがサポートするすべてのOracleデータベースのネイティブ・タイプと、それらに対応した、Oracleネイティブ・タイプを表す.NETタイプがリストされています。Oracleネイティブ・タイプを表すために複数の.NETタイプが使用される場合、最初の.NETタイプ・エントリは、Oracleネイティブ・タイプを最も適切に表します。3列目は、.NETタイプとして取得されるOracleネイティブ・タイプに対して起動される有効な型指定アクセッサを示します。無効な型指定アクセッサが列に使用された場合、InvalidCastException
がスローされます。Oracleネイティブ・データ型は、データベースのバージョンに依存します。このため、Oracleデータベースの以前のバージョンでは使用できないデータ型もあります。
表3-11 .NETタイプのアクセッサ
Oracleネイティブ・データ型 | .NETタイプ | 型指定アクセッサ |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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.Int16
とSystem.Double
です。次に、列をNUMBER(20,10)
として定義してみます。この場合、列の値の範囲全体を表す.NETタイプが存在しないため、列の値をSystem.Decimal
タイプとして戻そうとします。列の値をSystem.Decimal
タイプとして表せない場合、例外が発生します。
OracleDataAdapter
のFill
メソッドは、OracleDataReader
オブジェクトを使用して、.NETタイプのDataTable
またはDataSet
を移入あるいはリフレッシュします。その結果、DataTable
またはDataSet
のNUMBER
列を表すために使用される.NETタイプも、その列の精度とスケールに依存します。
ODP.NETは、データベースのデータ型をネイティブに表すプロバイダ固有のタイプを公開します。これらのODP.NETタイプにより、対応する.NETタイプよりもパフォーマンスおよび機能性が上回る機能が提供される場合があります。ODP.NETタイプは、それぞれの型指定アクセッサをコールすることで、OracleDataReader
オブジェクトから取得できます。
表3-12には、ODP.NETがOracleネイティブ・タイプのODP.NETタイプを取得する際に使用する有効なタイプのアクセッサがリストされています。
表3-12 ODP.NETタイプのアクセッサ
Oracleネイティブ・データ型 | ODP.NETタイプ | 型指定アクセッサ |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
OracleRef |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ODP.NETは、OracleDataReader
オブジェクトでRead
メソッドを起動中に、データベースから行をフェッチおよびキャッシュします。この操作により取得されるLONG
およびLONG
RAW
列データの量は、InitialLONGFetchSize
により決定されます。InitialLONGFetchSize
が、0
、0
より大きな値および-1
に設定されている場合の動作の違いは、次の各項で説明します。
注意: ODP.NETでは、CommandBehavior.SequentialAccess 列挙値はサポートされていません。このため、LONG およびLONG RAW データはランダムにフェッチできます。 |
OracleDataReader
オブジェクトでRead
メソッドを起動中に、LONG
またはLONG
RAW
列データに対して指定された、InitialLONGFetchSize
の文字数またはバイト数がキャッシュに取り出されます。
デフォルトでは、InitialLONGFetchSize
は0に設定されています。この場合ODP.NETは、OracleDataReader
オブジェクト上でのRead
メソッドの起動中、LONG
またはLONG
RAW
列データのいずれもフェッチしません。データがキャッシュされないため、データベースのラウンド・トリップの原因となるLONG
またはLONG
RAW
列に対して型指定アクセッサ・メソッドが明示的に起動されると、LONG
またはLONG
RAW
データがフェッチされます。
InitialLONGFetchSize
が0
より大きな値に設定された場合、OracleDataReader
オブジェクトでRead
メソッドを起動すると、ODP.NETにより、指定された量のデータがキャッシュされます。アプリケーションが型指定アクセッサ・メソッドによりInitialLONGFetchSize
以下のデータ量を要求した場合、データベース・ラウンドトリップは発生しません。ただし、InitialLONGFetchSize
を超えるデータをフェッチするには、追加のデータベース・ラウンドトリップが必要です。
InitialLONGFetchSize
文字数またはバイト数よりも多くのデータを取得するには、選択リストに次のいずれかが必要です。
主キー
ROWID
一意の列: (一意制約が定義されたか、または一意索引が作成された1セットの列として定義されたもの。セット内の少なくとも1列には、ここで定義されたNOT
NULL
制約があります)
選択リストに主キー列(ROWID
)または一意の列がない状態で、LONG
またはLONG
RAW
データ全体をフェッチするには、OracleCommand
オブジェクトのInitialLONGFetchSize
プロパティのサイズを、検索に必要な文字数またはバイト数以上に設定します。
OracleDataReader
オブジェクトで適切な型指定アクセッサ・メソッド(LONG
の場合GetChars
、GetOracleString
またはGetString
、LONG
RAW
の場合GetOracleBinary
またはGetBytes
)がコールされたときに、LONG
またはLONG
RAW
データが戻されます。
InitialLONGFetchSize
を-1
に設定すると、選択リストに主キー、ROWID
または一意の列を必要とせずに、SELECT問合せに対してデータベースからLONG
またはLONG
RAW
データ全体をフェッチできます。
InitialLONGFetchSize
が-1
に設定されると、OracleDataReader
オブジェクトでRead
メソッドを起動中に、LONG
またはLONG
RAW
データ全体が取り出され、キャッシュされます。OracleDataReader
オブジェクトでGetString
、GetOracleString
、GetChars
、GetBytes
またはGetOracleBinary
をコールすると、列データ全体が戻されます。
ODP.NETは、OracleDataReader
オブジェクトでRead
メソッドを起動中に、データベースから行をフェッチおよびキャッシュします。この操作により取得されるLOB列データの量は、InitialLOBFetchSize
により決定されます。
次の各項では、InitialLOBFetchSize
が、0
、0
より大きな値および-1に設定されている場合の動作の違いを説明します。
デフォルトで、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
より大きな値に設定すると、OracleDataReader
オブジェクトに対するRead
メソッドを起動中に、ODP.NETにより、選択された各LOBに対してInitialLOBFetchSize
の文字数またはバイト数までのLOBデータがキャッシュされます。
この項では、キャッシュされるInitialLOBFetchSize
文字数またはバイト数よりも多くのデータをフェッチする方法について説明します。この機能は、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(ゼロ)以外の値に設定すると、GetOracleBlob
、GetOracleClob
、GetOracleBlobForUpdate
およびGetOracleClobForUpdate
型指定アクセッサ・メソッドが無効になります。
Oracle Database 10gリリース2(10.2)以上では、InitialLOBFetchSize
プロパティに設定された値に関係なく、型指定アクセッサが起動されるとLOBデータ全体が戻されます。指定されたInitialLOBFetchSize
よりも多くのデータを取得するために、主キー、ROWID
または一意の列を問合せ選択リストに含める必要はありません。
Oracle Database 10gリリース2以上では、InitialLOBFetchSize
が0
より大きな値であっても、GetOracleBlob
、GetOracleClob
、GetOracleBlobForUpdate
およびGetOracleClobForUpdate
メソッドを起動できるようになりました。
InitialLOBFetchSize
が0
より大きな値に設定されている場合に、アプリケーションがCLOB
列およびBLOB
列に対してコールできる型指定アクセッサ・メソッドの全リストを次に示します。
BLOB
列に対してコールできるメソッド
GetBytes
GetValue
GetValues
GetOracleBinary
GetOracleBlob
GetOracleBlobForUpdate
GetOracleValue
GetOracleValues
CLOB
列に対してコールできるメソッド
GetChars
GetString
GetValue
GetValues
GetOracleString
GetOracleClob
GetOracleClobForUpdate
GetOracleValue
GetOracleValues
InitialLOBFetchSize
を-1
に設定することで、選択リストに主キー、ROWID
または一意の列がない場合も、SELECT問合せに対してデータベースからLOBデータ全体をフェッチできます。InitialLOBFetchSize
が-1
に設定されると、OracleDataReader
オブジェクトでRead
メソッドを起動中に、LOB列データ全体がフェッチおよびキャッシュされます。OracleDataReader
オブジェクトでGetString
、GetOracleString
、GetChars
、GetBytes
またはGetOracleBinary
をコールすると、すべてのデータを取得できます。
この項では、InitialLOBFetchSize
プロパティが-1
に設定されている場合に、CLOB
およびBLOB
データ型に対してサポートされているメソッドとサポートされていないメソッドをリストしています。
表3-13では、CLOB
データ型に対してサポートされているメソッドとサポートされていないメソッドをリストしています。
表3-13 OracleDataReader CLOBメソッド
サポート対象 | サポート対象外 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
表3-14では、BLOB
データ型に対してサポートされているメソッドとサポートされていないメソッドをリストしています。
この項では、異なる状況における、InitialLOBFetchSize
プロパティの様々な設定のメリットおよびデメリットについて説明します。また、使用しているデータベース・リリースに応じたパフォーマンスの強化方法についても説明します。
InitialLOBFetchSize
プロパティをゼロ以外の値に設定すると、パフォーマンスが向上する場合があります。InitialLOBFetchSize
プロパティを使用すると、OracleBlob
オブジェクトまたはOracleClob
オブジェクトを使用して基礎となるLOBデータを検索するよりもパフォーマンスが向上します。これは、アプリケーションがOracleDataReader
オブジェクトからOracleBlob
オブジェクトおよびOracleClob
オブジェクトを取得する必要がなく、LOB列データのサイズがあまり大きくない場合に当てはまります。問合せで戻されるLOB列データのサイズがすべての行でほぼ同じ場合、InitialLOBFetchSize
は特に便利です。
通常、InitialLOBFetchSize
プロパティは、問合せで戻される行の80%以上のLOBデータのサイズより大きい値に設定することをお薦めします。たとえば、LOBデータのサイズが行の80%で1KB未満で、行の20%で1MB以上である場合、InitialLOBFetchSize
プロパティを1KBに設定します。
アプリケーションで、パフォーマンスとOracleBlob
およびOracleClob
機能のどちらをとるかを選択する必要はありません。InitialLOBFetchSize
プロパティを設定すると、パフォーマンスは向上し、OracleBlob
オブジェクトおよびOracleClob
オブジェクトを使用する自由度はそのままです。
LOBデータのサイズが不明であったり、LOBデータのサイズが不規則に変化する場合は、InitialLOBFetchSize
プロパティをデフォルト値の0
のままにしてください。これでも、ほとんどの場合でパフォーマンスが改善されます。
大部分の行についてInitialLOBFetchSize
プロパティのサイズをLOBデータ・サイズ以上に設定すると、パフォーマンスが劇的に改善されます。通常、InitialLOBFetchSize
プロパティは、問合せで戻される行の80%以上のLOBデータのサイズより大きい値に設定することをお薦めします。たとえば、LOBデータのサイズが行の80%で1KB未満で、行の20%で1MB以上である場合、InitialLOBFetchSize
プロパティを1KBに設定します。
アプリケーションのパフォーマンスは、アプリケーションがフェッチする必要のある行数と、行の検索に必要なデータベース・ラウンドトリップの回数に依存します。
FetchSize
プロパティは、データベース・ラウンドトリップからフェッチされたデータをキャッシュするためにODP.NETが割り当てるメモリー・サイズの合計をバイトで表したものです。
FetchSize
プロパティは、状況に応じてOracleCommand
またはOracleDataReader
オブジェクトで設定できます。また、OracleCommand
オブジェクトのFetchSize
プロパティはOracleDataReader
オブジェクトにより継承され、変更できます。
FetchSize
プロパティをOracleCommand
オブジェクトで設定した場合、新しく作成されたOracleDataReader
は、OracleCommand
オブジェクトのFetchSize
プロパティを継承します。この継承されたFetchSize
は、そのままにしておくか、継承された値を上書きするように変更できます。OracleDataReader
オブジェクトのFetchSize
プロパティは、最初のRead
メソッドを起動する前に変更できます。このメソッドは、FetchSize
プロパティで指定されたメモリーを割り当てます。データベースからの後続のフェッチはすべて、そのOracleDataReader
に割り当てられた同じキャッシュを使用します。このため、最初のRead
メソッドを起動した後にFetchSize
を変更しても影響はありません。
FetchSize
プロパティを微調整することで、アプリケーションは、メモリー使用率、および1回のデータベース・ラウンドトリップでフェッチされる行数を制御して、パフォーマンスを向上させることができます。たとえば、問合せが100行を戻し、各行が1024バイトある場合、FetchSize
プロパティを102400に設定すると、1回のデータベース・ラウンドトリップで100行をフェッチできます。同じ問合せで、FetchSize
プロパティを10240に設定すると、100行を検索するのに10回のデータベース・ラウンドトリップが必要になります。アプリケーションが結果セットからすべての行をフェッチする必要がある場合、最初の使用例の方が2番目の使用例より高速になります。ただし、アプリケーションが結果セットから最初の10行のみをフェッチする必要がある場合、100行ではなく10行のみをフェッチするため、2番目の使用例の方がパフォーマンスが向上します。
OracleCommand
オブジェクトのRowSize
プロパティは、SELECT
文の実行後に行サイズ(バイト)とともに移入されます。FetchSize
プロパティは、RowSize
プロパティとデータベース・ラウンドトリップごとにフェッチされる行数の積に設定することで、RowSize
プロパティに相対的な値に設定できます。
たとえば、FetchSize
をRowSize
* 10に設定すると、OracleDataReader
オブジェクトでは、データベース・ラウンドトリップごとに10行のみが強制的にフェッチされます。各列のデータ長によってRowSize
が変わることはありません。RowSize
は、SELECT
文が実行されるデータベース表のメタデータ情報から正確に決定されます。
RowSize
プロパティを使用すると、次の項で説明するように、設計時または実行時にFetchSize
プロパティを設定できます。
HKLM¥Software¥Oracle¥ODP.NET¥
version
¥FetchSize
レジストリ・エントリは、特定のバージョンのODP.NETを使用するすべてのアプリケーションに対するデフォルトの結果セットのフェッチ・サイズをバイト単位で指定するように設定できます。または、アプリケーション構成ファイルまたはweb.config
ファイルのFetchSize
属性で、特定のアプリケーションに対するデフォルト値を指定できます。デフォルトのフェッチ・サイズは65536バイトです。この値は、実行時にアプリケーションのFetchSize
プロパティをOracleCommand
またはOracleDataReader
に対してプログラムで設定することによって無視できます。
特定のSELECT
文の行サイズが前の実行ですでにわかっている場合、OracleCommand
オブジェクトのFetchSize
値は、設計時に、その行サイズとアプリケーションがデータベース・ラウンドトリップごとにフェッチする必要がある行数の積に設定できます。OracleCommand
オブジェクトのFetchSize
値セットは、OracleCommand
オブジェクトでExecuteReader
メソッドを起動したときに作成されたOracleDataReader
オブジェクトにより継承されます。OracleCommand
オブジェクトでFetchSize
を設定するのではなく、OracleDataReader
で直接FetchSize
を設定することもできます。いずれの場合にも、実行時にRowSize
プロパティ値にアクセスしなくても、FetchSize
は設計時に設定されます。
設計時に行サイズがわからないアプリケーションでは、OracleCommand
オブジェクトのRowSize
プロパティを使用して、OracleDataReader
オブジェクトのFetchSize
プロパティを設定できます。RowSize
プロパティは、行のサイズに基づいて、動的な方法でFetchSize
プロパティを設定します。
OracleCommand
オブジェクトでExecuteReader
メソッドを起動してOracleDataReader
オブジェクトを取得した後に、RowSize
プロパティが行のサイズ(バイト)とともに移入されます。RowSize
プロパティを使用することで、アプリケーションは、OracleDataReader
オブジェクトのFetchSize
プロパティを、RowSize
プロパティ値とアプリケーションがデータベース・ラウンドトリップごとにフェッチする必要がある行数の積に動的に設定できます。この使用例では、実行時にRowSize
プロパティにアクセスすることでFetchSize
が設定されます。