アプリケーションでの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_IN、TTCmd::PARAM_OUTまたはTTCmd::PARAM_INOUTになります。 -
sqltypeは、データのSQLデータ型です(たとえば、SQL_INTEGER)。 -
precisionとscale(どちらもオプション)は、ODBCSQLBindParameterコールの場合と同様に使用します。プリミティブ型(intなど)については、precisionとscaleの設定は無視されます。
ノート:
例については、出力または入力/出力パラメータのバインドを参照してください。その他の参考情報については、registerParam()も参照してください。
パラメータのCデータ型からSQLデータ型へのマッピング
入力パラメータの場合、TTClassesはデフォルトで、setParam()またはBindParameter()コールに対して、マッピングに従って、バインドされたCデータ型からSQLデータ型を導出します。
通常、入力パラメータにregisterParam()コールは不要ですが、特定のSQLデータ型、精度またはスケールを使用する必要がある場合は、コールすることが可能です。
表2-1 TTClasses Cデータ型のSQLデータ型へのマッピング
| Cデータ型 | SQLデータ型 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ノート:
ドライバ・マネージャを使用している場合、前述の表のすべての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 :baの両方の出現に対して同じ値を使用するには、次のように指定します。
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を使用するステップを示しています。
-
REF CURSORを返すPL/SQL文に対して、
TTCmdオブジェクトを宣言します(この例ではcmdPLSQL)。 -
TTCmd*ポインタを宣言して、REF CURSOR用の2つ目のTTCmdオブジェクトをポイントします(この例ではcmdRefCursor)。 -
最初の
TTCmdオブジェクト(cmdPLSQL)を使用してPL/SQL文を準備します。 -
最初の
TTCmdオブジェクトのTTCmd::registerParam()メソッドを使用して、このREF CURSORを出力パラメータとして登録します。 -
最初の
TTCmdオブジェクトを使用して、文を実行します。 -
最初の
TTCmdオブジェクトのTTCmd::getParam()メソッドを使用して、REF CURSORを2つ目のTTCmdオブジェクト(&cmdRefCursorを使用)に取得します。REF CURSORには、getParam(intparamNo, TTCmd**rcCmd)のシグネチャがあります。 -
REF CURSORの
TTCmdオブジェクトから結果をフェッチして、必要に応じて処理します。 -
最初の
TTCmdオブジェクトを削除します。 -
REF CURSORの
TTCmdオブジェクトへのポインタを削除します。 -
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からアプリケーションへの
OUTREF 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_BINARY、SQL_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)が含まれます。
その内容は次のとおりです。
次の情報も参照できます。
-
LOBとCおよびC++向けLOBプログラミング・インタフェースの概要については、Oracle TimesTen In-Memory Database C開発者ガイドのラージ・オブジェクト(LOB)。LOBの簡易データ・インタフェースのみをTTClassesに適用可能です。
-
TimesTenでのLOBに関する詳細は、Oracle TimesTen In-Memory Database SQLリファレンスのLOBデータ型
-
LOBを使用したプログラミングに関する一般的な情報(TimesTenの機能に限定されていない情報)については、『Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイド』
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型に対して実行されるメソッドは、NCHAR、BINARYおよび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;
}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オペレーション・ガイドの自動クライアント・フェイルオーバーの使用を参照してください。