TOracleQueryによるSELECT文の実行

TOracleQueryはTDataSetとの互換性がないため、フィールド値の取得方法もBDEのようにTFieldを使用しません。プロジェクトによっては、この点を嫌って、データのSELECTにはTOracleDataSetしか使わないということでもよいと思います。

TOracleQueryのメンバで、SELECTクエリの実行時によく使われると思われるものは以下のとおりです。

  • TQuery : クエリの設定と実行に関する基本メンバ

    • property
      Session : 有効なTOracleSessionをセットします
    • property
      SQL : 実行するSQL文、またはPL/SQLブロックを文字列でセットします
    • procedure
      Execute : SQL文を実行します(SELECT,UPDATEとも)
    • property
      Active :
      Active:=Trueは、Openと同じです。設計時にデータセットを開くときにはこちらを使います
    • proceure
      Close : カーソルを閉じてリソースを解放します。Active:=Falseでも同じです
  • TOracleQuery : SELECT結果にアクセスするための基本メンバ

    • function
      Eof :
      取得したレコードセットが0件のときと、末尾まで読み出しを終ったときにTrueになります
    • procedure
      Next : 次の1件を読み出します
    • function
      FieldIsNull(FieldName: string) : Boolean; : フィールドがNULLかどうかを判定します
    • function
      Field(FieldName: string): Variant; フィールドの値を返します
    • function
      FieldAsInteger,
      FieldAsString,
      FieldAsDate,
      FieldAsFloat : Field(
      …).As… と代替できます

例1:SELECT文のみをSQLにセットする場合

たとえば、以下のSQLを実行し、取得されたレコードを順に1回スキャンするとします。

  SELECT * FROM EMP

このような場合、TQueryのSQLプロパティに上記のSQLをセットして、以下のようにしてデータにアクセスできます。(クエリを実行する時点で、Sessionプロパティに有効なセッションが指定されている必要があります。この点については、今後は記述を省略します。)以下の例でFieldを使ったり、FieldAsStringを使ったりしているのは説明のためです。実際にはプロジェクトスタンダードでどちらかに統一しましょう。

  procedure TForm1.Button1Click(Sender: TObject);
  begin
    with OracleQuery1 do
    try
      Execute;

      while not Eof do begin
        Memo1.Lines.Add(
          '番号:' + Field('EMPNO') + #9 +
          '名前:' + FieldAsString('ENAME') + #9 +
          '入社日:' + FormatDateTime('YYYY"年"MM"月"DD"日"',
FieldAsDate('HIREDATE'))
        );
        Next;
      end;
    except
      on E: EOracleError do showmesage(E.Message);
    end;
  end;

これを実行すると、Memoコンポーネントには例えば次のように出力されるはずです。

  番号:7369 名前:SMITH  入社日:1980年12月17日
  番号:7499 名前:ALLEN  入社日:1981年02月21日
  番号:7521 名前:WARD   入社日:1981年02月22日
  ... 以下略 ...

なお、SELECTを実行する場合、検索結果が
0件でも例外は発生しません。EOracleErrorが発生するのは、SQLに文法上の誤りがあったり、テーブルやビューやカラムの名称が間違っていたり、セッションが切れていたりする場合に限りますので、複雑な例外処理はおそらく不要でしょう。

Field関数や、
FieldAs***関数は、実際にはオーバーロード関数で、たとえば function Field(FieldId:
integer): Variant; と function Field(FieldName: string): Variant; の両方が定義されています。
FieldIdは、SELECT文で取得したカラムに対してふられる、ゼロベース(最初のカラムのFieldIdがゼロ)のインデックスです。

Field関数で、フィールドの値を取得する際に、カラムデータが
NULL値である場合の動作は、セッションのNullValueプロパティ次第で変わります。デフォルトでは、データベース上のNULL値は、Variant型のNull変数の値が返されます。Delphiのヘルプで「Null変数」を引いてみてください。セッションのNullValueプロパティを変更すると、Variant型のUnassigned定数が返されるようになります。Delphiのヘルプで「Unassigned定数」を参照してください。おそらく、デフォルト値のままで使うほうが無難でしょう。

SELECTのパフォーマンスチューニング

  • TOracleQuery * property
    ReadBuffer :
    一度に読み込むレコード件数を指定します。(デフォルトは25)ただし、クエリにLONG/LONG
    RAW
    項目が含まれる場合は、バッファリングは行われません。(1を指定したと同じになります)

DOAは、SELECT結果をサーバから取得する際にバッファリングを行いますが、一度に読み込むレコード件数をReadBufferプロパティでコントロールします。デフォルト値は比較的小さいので、この値を大きくすることで、パフォーマンスが大いに向上する可能性があります。
TOracleDataSetにも同じプロパティがあります。

LONG/
LONG
RAW
型を使用すると、このバッファリングが行われなくなります。したがって、LONG/
LONG RAWは使わないほうがよいでしょう。Oracle8 以降であれば、
CLOB/
BLOB /
BFile 型を使うべきです。
DOAを使えば、これらすべての型にアクセスできます。