アプリケーションでのTimesTen機能の使用

この項では、データの操作に関して、次の内容で説明します。

パラメータのバインド

この項では、SQL文のパラメータのバインドについて説明します。

ノート:

TimesTen開発者ガイドで使用される「バインド・パラメータ」という用語(ODBC用語に準拠)は、TimesTenのPL/SQLのマニュアルで使用される「バインド変数」という用語(Oracle Database PL/SQL用語に準拠)と同じです。

パラメータのバインドについて

TTCmdクラスには、パラメータをバインドするメソッドsetParam()BindParameter()(バッチ操作用)が用意されています。また、出力および入力/出力パラメータをサポートするため、またはデフォルトのバインド・タイプを上書きするためのregisterParam()も用意されています。

TimesTenのバインド・メカニズム(アーリー・バインディング)はOracle Databaseのバインド・メカニズム(レイト・バインディング)とは異なります。TimesTenは、問合せの準備の前にデータ型を必要とします。そのため、各バインド・パラメータのデータ型が指定されていないかSQL文から推測できないと、エラーが発生します。たとえば次のような文が、これに該当します。

SELECT 'x' FROM DUAL WHERE ? = ?;

この問題には、たとえば次のように対処できます。

SELECT 'x' from DUAL WHERE CAST(? as VARCHAR2(10)) = 
                           CAST(? as VARCHAR2(10)); 

入力パラメータのバインド

バッチ以外の操作については、TTCmd::setParam()メソッドを使用して、SQL文の入力パラメータをバインドします(パラメータの位置とバインドする値を指定します)。バッチ操作では、TTCmd::BindParameter()メソッドを使用します。

(バッチ操作の例については、setParam()およびExecuteBatch()を参照してください。)

バッチ以外の操作については、次の例にクラスSampleConnectionのスニペットを示します。この例では、表に行を挿入するためにパラメータがバインドされます。(この例は、TimesTen Classicクイック・スタートで提供されているbasics.cppサンプル・アプリケーションのものです。TimesTenクイック・スタートおよびサンプル・アプリケーションについてを参照してください。

次のように定義される表basicsがあるとします。

create table basics (name char(10) not null primary key, i tt_integer);

ここでは、Connect()メソッドの実装が省略されていますが、Connect()の実装例については、TTCmd、TTConnectionおよびTTConnectionPoolの使用で確認できます。

class SampleConnection : public TTConnection 
{
  using TTConnection::Connect;
 
  private:
    TTCmd        insertData;
    ...
 
  protected:
 
  public:
    SampleConnection();
    ~SampleConnection();
    virtual void Connect(const char* connStr, 
                         DRIVER_COMPLETION_ENUM driverCompletion);
    void insert(char* nameP);
    ...
 
  ...
  // Assume a Connect() method implemented with the following:
  // insertData.Prepare(this, "insert into basics values(:name, :value)");
  ...
}

//----------------------------------------------------------------------
 

void
SampleConnection::insert(char* nameP)
{
  static long i = 0;
  insertData.setParam(1, nameP);
  insertData.setParam(2, i++);
  insertData.Execute();
}
 
//----------------------------------------------------------------------

...

int
main(int argc, char** argv)
{
  ...
  char name[10];
  SampleConnection conn;
  ...

// Assume conn is an open connection.
  sprintf(name, "Robert");
  try {
    conn.insert(name); 
  }
  catch (TTStatus st) {
    cerr << "Error inserting row " << name << ":" << st << endl;
    conn.Rollback();
  }
}

パラメータの登録

TTCmdクラスには、パラメータのSQLデータ型、精度、スケール(該当する場合)およびパラメータが入力、出力または入力/出力であるかどうかを指定できるメソッドregisterParam()が用意されています。

registerParam()コールは、出力または入力/出力パラメータに関して必要です(REF CURSOR(出力のみ)、あるいはPL/SQL RETURNING INTO句(出力のみ)、プロシージャまたは関数からのパラメータが考えられます)。

registerParam()コールは、関連するsetParam()またはBindParameter()コールの前後どちらかで使用可能であり、そのSQLデータ型、精度、スケール(該当する場合)に関しては優先されます。

メソッドのシグネチャは、次のように指定します。

inline void
TTCmd::registerParam(int   pno,
                     int   inputOutputType, 
                     short sqltype, 
                     int   precision = 0, 
                     short scale = 0)
  • pnoは、文内のパラメータの位置を表します。

  • inputOutputTypeは、TTCmd::PARAM_INTTCmd::PARAM_OUTまたはTTCmd::PARAM_INOUTになります。

  • sqltypeは、データのSQLデータ型です(たとえば、SQL_INTEGER)。

  • precisionscale (どちらもオプション)は、ODBC SQLBindParameterコールの場合と同様に使用します。プリミティブ型(intなど)については、precisionscaleの設定は無視されます。

ノート:

例については、出力または入力/出力パラメータのバインドを参照してください。その他の参考情報については、registerParam()も参照してください。

パラメータのCデータ型からSQLデータ型へのマッピング

入力パラメータの場合、TTClassesはデフォルトで、setParam()またはBindParameter()コールに対して、マッピングに従って、バインドされたCデータ型からSQLデータ型を導出します。

通常、入力パラメータにregisterParam()コールは不要ですが、特定のSQLデータ型、精度またはスケールを使用する必要がある場合は、コールすることが可能です。

表2-1 TTClasses Cデータ型のSQLデータ型へのマッピング

Cデータ型 SQLデータ型

char*

SQL_CHAR、SQL_VARCHAR

void*

SQL_BINARY、SQL_VARBINARY

double

SQL_FLOAT、SQL_DOUBLE

DATE_STRUCT

SQL_DATE

float

SQL_REAL、SQL_DECIMAL

int

SQL_INTEGER

SQLBIGINT

SQL_BIGINT

SQLCHAR*

SQL_VARCHAR

SQLINTEGER

SQL_INTEGER

SQLSMALLINT

SQL_SMALLINT

SQLTINYINT

SQL_TINYINT

SQLWCHAR*

SQL_WCHAR、SQL_WVARCHAR

TIME_STRUCT

SQL_TIME

TIMESTAMP_STRUCT

SQL_TIMESTAMP

SQLHSTMT

SQL_REFCURSOR

ノート:

ドライバ・マネージャを使用している場合、前述の表のすべてのCデータ型がサポートされている訳ではありません。ODBCドライバ・マネージャ使用時の考慮事項(Windows)を参照してください。

出力または入力/出力パラメータのバインド

TTClassesでは、REF CURSOR(出力のみ)などの出力および入/出力パラメータ、OUTまたはIN OUTパラメータを持つPL/SQLプロシージャまたはファンクションからのパラメータ、またはRETURNING INTO句からのパラメータ(出力のみ)がサポートされています。

TTClassesにSQL文内のパラメータが出力であるか入力/出力であるかを通知する場合は、前述の項で説明したTTCmd::registerParam()メソッドを使用する必要があります。このメソッド・コールのintputOutputTypeの設定には、TTCmd::PARAM_OUTまたはTTCmd::PARAM_INOUTを必要に応じて使用します。

バッチ以外の操作では、SQL文の実行後に、適切なTTCmd::getParam()メソッドを使用し出力値を取得します(パラメータの位置および値の配置先の変数を指定します)。各データ型にはシグネチャがあります。

バッチ操作では、TTCmd::BindParameter()を、出力パラメータ、入力/出力パラメータまたは入力パラメータに使用します。これは文が実行される前にコールされます。文の実行後、出力値用のデータはBindParameter()コールで指定したバッファ内に配置されます。BindParameter()には、データ型ごとにシグネチャがあります。バッチ操作の入力/出力パラメータ用には、文の実行前にBindParameter()が1回のみコールされます。指定したバッファには、実行前には入力が含まれ、文の実行後には出力が含まれます。

次の例は、出力および入力/出力パラメータの使用方法を示す部分的なコードです。

最初の例では、入力パラメータと出力パラメータを使用します。setParam()コールで、入力パラメータ:aの値をバインドされます。getParam()コールで、出力パラメータ:bの値を取得されます。この出力パラメータも、必要に応じて登録されます。

...
// t1 has a single TT_INTEGER column
cmd.Prepare(&conn, "insert into t1 values (:a) returning c1 into :b");
cmd.setParam(1, 99);
cmd.registerParam(2, TTCmd::PARAM_OUT, SQL_INTEGER);
cmd.Execute();
SQLINTEGER outval;

if (cmd.getParam(2, &outval))
  cerr << "The output value is null." << endl;
else
  cerr << "The output value is " << outval << endl;
...

その次の例では、バッチ操作で入力パラメータと出力パラメータを使用します。最初のBindParameter()コールは、最初のパラメータ:aの入力データを提供します。2番目のBindParameter()コールは、2番目のパラメータ:bの出力データ用にバッファを提供します。

...
#define BATCH_SIZE  5
int input_int_array[BATCH_SIZE] = { 91, 92, 93, 94, 95 };
int output_int_array[BATCH_SIZE] = { -1, -1, -1, -1, -1 };
SQLULEN numrows;
 
cmd.PrepareBatch(&conn, "insert into t1 values (:a) returning c1 into :b",
                 BATCH_SIZE);
cmd.BindParameter(1, BATCH_SIZE, input_int_array);
cmd.BindParameter(2, BATCH_SIZE, output_int_array);
cmd.registerParam(2, TTCmd::PARAM_OUT, SQL_INTEGER);
numrows = cmd.ExecuteBatch(BATCH_SIZE);
...

次の例では、入力/出力パラメータを使用します。これは必要に応じて登録できます。setParam()コールはその入力値をバインドし、getParam()コールはその出力値を取得します。

...
cmd.Prepare(&conn, "begin :x := :x + 1; end;");
cmd.registerParam(1, TTCmd::PARAM_INOUT, SQL_INTEGER);
cmd.setParam(1, 99);
cmd.Execute();
SQLINTEGER outval;

if (cmd.getParam(1, &outval))
  cerr << "The output value is null." << endl;
else
  cerr << "The output value is " << outval << endl;
...

最後の例では、出力パラメータと入力/出力パラメータを使用します。次のPL/SQLプロシージャがあるとします。

create or replace procedure my_proc (
  a in number,
  b in number,
  c out number,
  d in out number ) as

begin
  c := a + b; 
  d := a + b - d; 
end my_proc;

このプロシージャの入力パラメータは、この例ではバインド・パラメータとしてではなく定数として取られるため、OUTパラメータおよびIN OUTパラメータのみがバインドされます。必要に応じて両方が登録されます。setParam()コールは、IN OUTパラメータ:var1の入力値を提供します。最初のgetParam()コールは、OUTパラメータ:sumの値を取得します。2番目のgetParam()コールは、IN OUTパラメータ:var1の出力値を取得します。

...
cmd.Prepare(&conn, "begin my_proc (10, 5, :sum, :var1); end;");
cmd.registerParam (1, TTCmd::PARAM_OUT, SQL_DECIMAL, 38);
cmd.registerParam (2, TTCmd::PARAM_INOUT, SQL_DECIMAL, 38);
cmd.setParam(2, "99");
cmd.Execute();
SQLINTEGER outval1, outval2;

if (cmd.getParam(1, &outval1))
  cerr << "The first output value is null." << endl;
else
  cerr << "The first output value is " << outval << endl;
if (cmd.getParam(2, &outval2))
  cerr << "The second output value is null." << endl;
else
  cerr << "The second output value is " << outval << endl;
...

重複パラメータのバインド

TimesTenでは、SQL文内に出現する複数の同名パラメータはそれぞれ異なるパラメータとみなされます。(これはOracle Databaseの重複パラメータのバインディングに関するサポートと一貫しています。)

ノート:

  • "TimesTenモード"の重複パラメータのバインドと、DuplicateBindMode接続属性は非推奨となっています。

  • Oracle TimesTen In-Memory Database C開発者ガイドSQL文での重複パラメータのバインドを参照してください。

次の問合せについて考えてみます。

SELECT * FROM employees
  WHERE employee_id < :a AND manager_id > :a AND salary < :b;

パラメータの位置番号が割り当てられるとき、名前の重複に関係なく、パラメータの出現ごとに番号が与えられます。アプリケーションは、少なくとも各パラメータ名の最初の出現時に値をバインドする必要があります。特定のパラメータ名がそれ以降に出現した場合は、アプリケーションはその出現に対して別の値をバインドすることも、そのパラメータの出現をバインドしないこともできます。後者の場合、最初の出現時と同じ値がそれ以降の出現時に使用されます。いずれの場合も、出現ごとに異なるパラメータ位置番号が付けられます。

この例では、前述のSQL文のaの2回目の出現に対して異なる値を使用しています。

mycmd.setParam(1, ...); // first occurrence of :a
mycmd.setParam(2, ...); // second occurrence of :a
mycmd.setParam(3, ...); // occurrence of :b

aの両方の出現に対して同じ値を使用するには、次のように指定します。

mycmd.setParam(1, ...); // both occurrences of :a
mycmd.setParam(3, ...); // occurrence of :b

パラメータbは、位置3に存在するとみなされ、パラメータ数は3とみなされます。

REF CURSORの使用

REF CURSORはPL/SQLの概念で、SQLの結果セット上のカーソルに対するハンドルであり、PL/SQLとアプリケーションの間で渡すことができます。

TimesTenでは、このカーソルをPL/SQL内で開くことができるため、REF CURSORをアプリケーションに渡して処理することができます。この使用方法は、OUT REF CURSORであり、これはPL/SQLに関するOUTパラメータです。すべての出力パラメータと同様に、これはTTCmd::registerParam()メソッドで登録する必要があります。

パラメータの登録および出力または入力/出力パラメータのバインドを参照してください。

TimesTenの実装では、REF CURSORは別の文ハンドルにアタッチされています。アプリケーションは、1つの文ハンドルにREF CURSORパラメータを持つSQL文を準備し、次に、この文の実行前に、2つ目の文ハンドルをREF CURSORの値としてバインドします。この文の実行後、アプリケーションはこの結果の記述、バインドおよびフェッチを、結果セットの場合と同じAPIを使用して実行することができます。

TTCmdオブジェクトは単一のSQL文をカプセル化するため、TTClassesでは2つのTTCmdオブジェクトが使用してこのREF CURSORモデルをサポートします。

REF CURSORの詳細は、Oracle TimesTen In-Memory Database PL/SQL開発者ガイドPL/SQL REF CURSORを参照してください。

ノート:

PL/SQLとアプリケーションの間でREF CURSORを渡す場合、TimesTenでは、PL/SQLからアプリケーションへのOUTREF CURSORのみがサポートされます。

次の例は、TTClassesでREF CURSORを使用するステップを示しています。

  1. REF CURSORを返すPL/SQL文に対して、TTCmdオブジェクトを宣言します(この例ではcmdPLSQL)。

  2. TTCmd*ポインタを宣言して、REF CURSOR用の2つ目のTTCmdオブジェクトをポイントします(この例ではcmdRefCursor)。

  3. 最初のTTCmdオブジェクト(cmdPLSQL)を使用してPL/SQL文を準備します。

  4. 最初のTTCmdオブジェクトのTTCmd::registerParam()メソッドを使用して、このREF CURSORを出力パラメータとして登録します。

  5. 最初のTTCmdオブジェクトを使用して、文を実行します。

  6. 最初のTTCmdオブジェクトのTTCmd::getParam()メソッドを使用して、REF CURSORを2つ目のTTCmdオブジェクト(&cmdRefCursorを使用)に取得します。REF CURSORには、getParam(int paramNo, TTCmd** rcCmd)のシグネチャがあります。

  7. REF CURSORのTTCmdオブジェクトから結果をフェッチして、必要に応じて処理します。

  8. 最初のTTCmdオブジェクトを削除します。

  9. REF CURSORのTTCmdオブジェクトへのポインタを削除します。

  10. delete文を発行して、REF CURSORのTTCmdオブジェクトを削除します。

この例では、PL/SQL無名ブロックからREF CURSORを取得および処理します。説明については、前述のステップを参照してください。

...
TTCmd  cmdPLSQL;
TTCmd* cmdRefCur;
TTConnection conn;
...
 
// c1 is a TT_INTEGER column.
cmdPLSQL.Prepare(&conn, "begin open :rc for select c1 from t; end;")
cmdPLSQL.registerParam(1, TTCmd::PARAM_OUT, SQL_REFCURSOR);
cmdPLSQL.Execute();

if (cmdPLSQL.getParam(1, &cmdRefCur) == false)
{
  SQLINTEGER fetchval;
 
  while (!cmdRefCursor->FetchNext()) {
    cmdRefCur->getColumn(1, &fetchval);
  }
  cmdRefCursor->Drop();
  delete cmdRefCursor;
}

cmdPLSQL.Drop();

TTClassesでREF CURSORを使用する場合は、次のような使用上のノートがあります。

  • PL/SQLとアプリケーションの間でREF CURSORを渡す場合、TimesTenでは、PL/SQLからアプリケーションへのOUT REF CURSORのみと、単一のREF CURSORのみを返す文がサポートされます。

  • 他のデータ型に対するTTCmd::getParam()コールとは異なり、REF CURSOR用のTTCmd**パラメータを使用したgetParam()コールは1回のみコールできます。それ以降のコールではNULLが返されます。REF CURSORを2度取得する必要がある場合は、文を再実行する必要があります。

  • 文を複数回実行する場合は、そのたびにREF CURSORパラメータを登録する必要があります。たとえば、ループ内で文の実行、REF CURSORパラメータの取得およびREF CURSORからのフェッチを行うには、次のようにパラメータの登録もループ内で行う必要があります。

    cmdPLSQL.Prepare(...);
    
    loop
       cmdPLSQL.registerParam(...);
       cmdPLSQL.Execute();
       cmdPLSQL.getParam(...);
       fetch loop
    end loop

    これについては、次の例に示します。

  • どのTTCmdオブジェクト(REF CURSOR用のものを含む)も、ODBC文ハンドルが割り当てられます。REF CURSOR文ハンドルは、Drop()文の実行時に削除され、そのリソースはdelete文の後に解放されます。

次の例では、REF CURSORをループ内で使用します。次の宣言とTTConnectionインスタンスconnを想定しています。

...
TTCmd query;
TTCmd* ref_cur;
...

ループは次のとおりです。

...
      cerr << "Selecting values using cursor" << endl;
      query.Prepare(&conn, "begin open :rc for select c1 from t1; end;");
      
      for (int round = 0; round < ROUNDS; round++) {
         cerr << "executing ref cursor round# " << (round+1) << endl;
         query.registerParam(1, TTCmd::PARAM_OUT, SQL_REFCURSOR);
         query.Execute();
         query.getParam(1, &ref_cur);
 
         while(true) {
            fetch_next = ref_cur -> FetchNext();
            if (fetch_next == 1)
                break;
 
            ref_cur -> getColumn(1, &val);
            cerr << "val = " << val << endl;
         }
         ref_cur->Drop();
         delete ref_cur;
      }
 
      conn.Commit();
      query.Drop();
...

ROWIDの使用

表の各行には、ROWIDと呼ばれる一意の識別子があります。アプリケーションでは、ROWID疑似列から行のROWIDを取得します。ROWIDはバイナリまたは文字形式で表すことができます。

アプリケーションは、リテラルのROWID値を、SQL文のWHERE句などで、一重引用符で囲んだCHAR定数として指定できます。

ODBC SQLデータ型のSQL_ROWIDは、SQLデータ型のROWIDと対応します。

パラメータおよび結果セット列では、ROWIDは、Cデータ型のSQL_C_BINARYSQL_C_WCHARおよびSQL_C_CHARとの間で双方向に変換可能です。SQL_C_CHARは、ROWIDのデフォルトのCデータ型です。ROWIDのサイズは、SQL_C_BINARYとしては12バイト、SQL_C_CHARとしては18バイトおよびSQL_C_WCHARとしては36バイトです。

通常、TTClassesでは文字列としてのROWIDがサポートされていますが、TTClassesアプリケーションでは、ROWIDを文字列としてではなくROWID型としてPL/SQL無名ブロックに渡せるようになったことに注意してください。そのためには、TTCmd::registerParam()メソッドを次の例に示すように使用して、ROWID入力パラメータをSQL_ROWID型として登録する必要があります。

...
TTConnection conn;
TTCmd cmd;
...
cmd.Prepare(&conn, "begin delete from t1 where rowid = :x; end;");
cmd.registerParam(1, TTCmd::PARAM_IN, SQL_ROWID);
cmd.setParam(1, rowid_string);
cmd.Execute();
...

ROWIDおよびROWIDデータ型の詳細は、使用方法と有効期間を含め、Oracle TimesTen In-Memory Database SQLリファレンスROWIDデータ型およびROWID擬似列を参照してください。

ノート:

TimesTenでは、PL/SQL型のUROWIDはサポートされません。

LOBの使用

この項では、TTClassesでのLOB (ラージ・オブジェクト)の使用について説明します。これには、CLOB(Character LOB)、NCLOB(各国語LOB)およびBLOB(バイナリLOB)が含まれます。

その内容は次のとおりです。

次の情報も参照できます。

TimesTenのLOBとOracle DatabaseのLOBの相違点

この項では、TimesTenとOracle DatabaseのLOBサポートの相違点について説明します。

  • LOBのTimesTenでの実装とOracle Databaseでの実装の主要な違いは、TimesTenでは、アプリケーションで使用されるLOBは、トランザクションが終了すると無効になるということです。そのようなLOBは、コミットまたはロールバック後、明示または暗黙にかかわらず、無効になります。DDL文の後も同様です。

  • TimesTenでは、BFILE、SecureFile、LOBに対する配列の読取りおよび書込みおよびLOBのコールバック関数はサポートされていません。

  • TimesTenでは、LOBの配列のバインドはサポートされていません。

  • TimesTenでは、LOBのバッチ処理はサポートされていません。

  • BLOBについては、TimesTenでの16進リテラルの使用に違いがあります。Oracle TimesTen In-Memory Database SQLリファレンス定数にあるHexadecimalLiteralについての説明を参照してください。

TTClassesでのLOBの簡易データ・インタフェースの使用

簡易データ・インタフェースを使用すると、他のスカラー型と同様に、アプリケーションからバインドおよび定義によってLOBデータにアクセスできます。

TTClassesの簡易データ・インタフェースでは、パラメータのバインドにgetParam()setParam()を使用し、結果行の定義にはgetColumn()またはgetColumnNullable()を使用します。アプリケーションは、SQLデータ型を使用してバインドまたは定義することが可能で、このSQLデータ型は次に示すように対応する変数型と互換性があります。

  • BLOBデータには、SQLデータ型のSQL_LONGVARBINARYとCデータ型のSQL_C_BINARYを使用します。

  • CLOBデータには、SQLデータ型のSQL_LONGVARCHARとCデータ型のSQL_C_CHARを使用します。

  • NCLOBデータには、SQLデータ型のSQL_WLONGVARCHARとCデータ型のSQL_C_WCHARを使用します。

ノート:

  • TTClassesでは、LOBのバッチ・モードはサポートされていません。

  • CLOBまたはNCLOBを、Cデータ型のSQL_C_BINARYとバインドすることは禁止されています。

次の例は、TTClassesでのLOBの簡易データ・インタフェースの使用を示しています。たとえば、ある表にNCLOB列、BLOB列およびCLOB列が作成されていて、データが移入されているとします。これらのLOB型に対して実行されるメソッドは、NCHARBINARYおよびCHARの場合とそれぞれ同じです。

#ifdef _WIN32
#include <ttcommon.h>
#endif
#include "TTInclude.h"
#define LOB_COL_SIZE 4194304

int main(int argc, char** argv) {

   TTConnection conn;
   TTCmd query;
   char conn_str[100] = "... your connection string ...";
   char tbl_name[20] = "... test table name ...";

   int num_rows = 0;
   char query_stmt[1000];
   int fetch_next;
   int value_is_null = 0;
   int column_type;
   SQLWCHAR * unicode_val;
   u_char * binary_val;
   char * alfanum_val;
   SQLLEN b_len;
   SQLLEN u_len;
 
   cerr << "Connecting to TimesTen <" << conn_str << ">" << endl;
 
   try {
      conn.Connect(conn_str);
      sprintf(query_stmt, "select * from %s", tbl_name);
      query.Prepare(&conn, query_stmt);
      query.Execute();
      const int num_result_cols = query.getNColumns();
 
      while (true) {
         // loop until no rows found
         // fetch a row; if no more rows, break out of loop
         // FetchNext returns 0 for success, 1 for SQL_NO_DATA_FOUND
         fetch_next = query.FetchNext();
         if (fetch_next == 1)
            break;
 
         for (int col = 1; col <= num_result_cols; col++) {
            value_is_null = 0;
            column_type = query.getColumnType(col);
 
            switch (column_type) {
 
               case SQL_WLONGVARCHAR:
 
                  value_is_null = query.getColumnNullable(col,
                          (SQLWCHAR**) & unicode_val, &u_len);
                  if (value_is_null) {
                     cerr << "NCLOB value is NULL";
                  } else {
                     cerr << "NCLOB value length = " << u_len << endl;
                     // do something with NCLOB value
                  }
                  break;
 
               case SQL_LONGVARBINARY:
 
                  value_is_null = query.getColumnNullable(col,
                          (void**) & binary_val, &b_len);
                  if (value_is_null) {
                     cerr << "BLOB value is NULL";
                  } else {
                     cerr << "BLOB value length = " << b_len << endl;
                     // do something with BLOB value
                  }
                  break;
 
               case SQL_LONGVARCHAR:
 
                  alfanum_val = (char*) malloc(LOB_COL_SIZE + 1);
                  value_is_null = query.getColumnNullable(col, alfanum_val);
                  if (value_is_null) {
                     cerr << "CLOB value is NULL";
                  } else {
                    cerr << "CLOB value length = " << strlen(alfanum_val) << endl;
                     // do something with BLOB value
                  }
                  free(alfanum_val);
                  break;
 
               default:
                  break;
            }
         }
 
         num_rows++;
         cerr << "row " << num_rows << " fetched" << endl;
      }
      cerr << num_rows << " rows returned" << endl;
   } catch (TTError err) {
      cerr << "\nError" << err << endl;
   }
   query.Drop();
   conn.Disconnect();
   return 0;
}

TTClassesでのパススルーLOB

パススルーLOBは、TimesTenを介してアクセスされるOracle DatabaseのLOBであり、TimesTen LOBとして公開され、TimesTen LOBとほぼ同様にTimesTenでサポートされます。

ただし、次のことに注意してください。

  • TimesTen LOBのサイズ制限は、パススルーによるOracle DatabaseのLOBの格納には適用されません。

  • TimesTenのローカルLOBと同様に、アプリケーションで使用されるパススルーLOBは、トランザクションが終了すると無効になります。

SQL文を実行するためのタイムアウトまたはしきい値の設定

TimesTenには、SQL文またはプロシージャ・コールの実行時間を制限する方法として、タイムアウト値の設定と、しきい値の設定の2つがあります。

タイムアウト値を設定すると、タイムアウト時間に達すると、文の実行が停止し、エラーがスローされます。値0はタイムアウトがないことを示します。しきい値を設定すると、しきい値に達するとサポート・ログに警告が書き込まれますが、実行は続行されます。値0は警告がないことを意味します。

問合せのタイムアウト制限は、SQL文がアクティブに実行されている場合にのみ有効です。コミット中またはロールバック中にはタイムアウトは発生しません。

TTCmdオブジェクトに対し、これらを設定するには、TTCmdメソッドのsetQueryTimeout()およびsetQueryThreshold()を指定します。これらのメソッドは、TimesTenの接続属性SQLQueryTimeout (またはSQLQueryTimeoutMsec)およびQueryThresholdのそれぞれの設定をオーバーライドする点に注意してください。これらの各接続属性のデフォルト値は0で、タイムアウトまたはしきい値が設定されていません。

getQueryThreshold()メソッドでは、現在のしきい値の設定を読み取ることもできます。

これらの機能は、TTClassesでは、文レベルのみで使用でき、接続レベルでは使用できません。

Oracle TimesTen In-Memory Database C開発者ガイドSQL実行に対するタイムアウトおよびしきい値を参照してください。タイムアウト値の関係については、Oracle TimesTen In-Memory Databaseオペレーション・ガイドSQLおよびPL/SQLのタイムアウト値の選択を参照してください。

ノート:

ロック・タイムアウト値およびSQL問合せのタイムアウト値の両方が指定されている場合は、まず、2つの値の小さい方の値によってタイムアウトが発生します。ロック・タイムアウトについては、Oracle TimesTen In-Memory DatabaseリファレンスttLockWait(組込みプロシージャ)またはLockWait(一般接続属性)、またはOracle TimesTen In-Memory Databaseモニタリングおよびトラブルシューティング・ガイドデッドロックとタイムアウトの確認を参照してください。

TTClassesアプリケーションでの自動クライアント・フェイルオーバーの使用

TTClassesには、独自の自動クライアント・フェイルオーバー機能はありませんが、ODBCアプリケーションの場合と同様にTTClassesアプリケーションでTimesTen自動クライアント・フェイルオーバーを構成できます。

これについては、Oracle TimesTen In-Memory Database C開発者ガイド自動クライアント・フェイルオーバーのODBCサポートで説明されています。TimesTen Scaleoutについては、Oracle TimesTen In-Memory Database Scaleoutユーザーズ・ガイドクライアント接続フェイルオーバーも参照してください。TimesTen Classicについては、Oracle TimesTen In-Memory Databaseオペレーション・ガイド自動クライアント・フェイルオーバーの使用を参照してください。