アプリケーションでの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 :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を使用するステップを示しています。
-
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(int
paramNo
, 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からアプリケーションへの
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_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オペレーション・ガイドの自動クライアント・フェイルオーバーの使用を参照してください。