|
Example - Long & Long Raw |
Top Previous Next |
|
これら2つのOracleデータ型は非常に大きな値(最大2GB)を取れます。それゆえ、Long値に関する制約はあまりありません:
Long Rawは、文字列かバイトのゼロベースバリアント配列として扱われます。可能な限りハイパフォーマンスでバイト配列にアクセスするために、VarArrayLockとVarArrayUnlock関数を使ってください。値のサイズを調べるためにはVarArrayHighBoundを使ってください。 次のサンプルは絵をフェッチし、サイズを調べ、ディスクにバイナリーデータを保存します: // SelectEmpPictureQuery.SQL = // select picture from emp // where empno = :empno try with SelectEmpPictureQuery do begin SetVariable('EMPNO', Emp.EmpNo); Execute; Picture := Field('PICTURE'); Size := VarArrayHighBound(Picture, 1) + 1; Ptr := VarArrayLock(Picture); WriteFile('Employee.gif', Ptr^, Size); VarArrayUnlock(Picture); end; except on E:EOracleError do ShowMessage(E.Message); end;
LongとLong Rawデータに簡単に素早くアクセスするために2つの低レベルメソッドが用意されています。FieldとSetVariableメソッドは全てのデータ型に対して一貫したアクセスを提供します。しかしメモリー使用、メモリー移動そしてデータベースアクセスにおいて若干のオーバーヘッドが発生します。 もしLongかLong Rawの内部構造を知っていれば、正確なサイズもわかり、最低限のネットワーク往復で正確に必要なものをフェッチできるでしょう。GetLongField メソッドは次のような状況で使えます: GetLongField(FieldId: Integer; Buffer: Pointer; Offset, Length: Integer): Integer
例えば、もしLong Rawカラムが16-colorビットマップだとわかっていれば、高さと幅が18と22の位置に格納されていることもわかっているはずです。もし最初にこれら2つのIntegerをフェッチすれば、ビットマップのサイズを判断でき残りをフェッチすることが出来ます: var wh: TPoint; Size: Integer; Bitmap: Pointer; begin Query.GetLongField(BmpField, @wh, 18, SizeOf(wh)); Size := ((wh.x * wh.y) div 2) + 70; GetMem(Bitmap, Size); Query.GetLongField(BmpField, Bitmap, 0, Size); ... end;
もしLongかLong Raw変数の値を設定するためにSetVariableメソッドを使うなら、値に文字列(LongかLong Raw)かバイトのバリアント配列(Long Raw)を渡す必要があります。しかし多量のメモリーを変換しコピーする代わりに使うデータへのポインターを渡すほうがより効果的です。SetLongVariableメソッドでこうすることができます: SetLongVariable(Name: String; Buffer: Pointer; Length: Integer)
Bufferポインターによって指し示されたメモリーはコピーされず、クエリーが実行されるまで有効なまま保たれます。次のサンプルは変数をメモリ内のある録音されたwavファイルに設定し、新しいレコードを挿入します: var WavBuffer: Pointer; WavLength: Integer; begin RecordWavFile(WavBuffer, WavLength); Query.SetVariable('wavname', WavName.Text); Query.SetLongVariable('wavfile', WavBuffer, WavLength); Query.Execute; FreeMem(WavBuffer, WavLength); end;
注: GetLongFieldとSetLongVariableメソッドは低レベルであるため、FieldとSetVariableメソッドと違ってLong値のためにLFとCR/LF間の変換を行いません。Long Raw値に関してはこのことは問題になりません。 |