この項では、TimesTenデータ・ストアのデータの処理について説明します。
内容は次のとおりです。
SQLを使用してTimesTenデータ・ストアのデータを管理する方法については、『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』のTimesTenデータ・ストアのデータの処理に関する章を参照してください。この項では、Cアプリケーション内でSQL文をコールするために使用される一般的な書式について説明します。
次の書式を使用し、SQLExecDirect関数を指定してSQL文をコールします。
#include <sql.h> SQLRETURN rc; SQLHSTMT hstmt; ... rc = SQLExecDirect(hstmt, (SQLCHAR*) "SQL Statement", SQL_NTS); if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) ... /* handle error */
たとえば、次のCコード・フラグメントでは、CustIdおよびCustNameの2つの列を持つNameIDという名前の表を作成します。この表では、名前(文字)が識別子(整数)にマップされます。
#include <sql.h> SQLRETURN rc; SQLHSTMT hstmt; ... rc = SQLExecDirect(hstmt, (SQLCHAR*) "CREATE TABLE NameID (CustId INTEGER, CustName VARCHAR(50))", SQL_NTS); if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) ... /* handle error */SQLの詳細は、『Oracle TimesTen In-Memory Database APIおよびSQLリファレンス・ガイド』を参照してください。
標準のODBC機能を拡張するTimesTen組込みプロシージャについては、『Oracle TimesTen In-Memory Database APIおよびSQLリファレンス・ガイド』の組込みプロシージャに関する章を参照してください。これらのプロシージャは、ODBCのコール・インタフェースを使用して起動できます。書式は次のとおりです。
次のODBCの例では、ttCkptプロシージャをコールしてファジー・チェックポイントを開始します。
次のJDBCの例では、ファジー・チェックポイントを開始します。
TimesTenによるODBCの拡張によって、アプリケーションは1回のコールでTimesTenデータ・ストアから複数のデータ行をプリフェッチできます。複数のデータ行をフェッチすることによって、コミット読取り分離レベルを使用しているアプリケーションのパフォーマンスを向上できます。
TT_PREFETCH_COUNT属性は、SQLSetConnectOptionまたはSQLSetStmtOptionのコールで使用されます。値には0(ゼロ)から128までの任意の整数が設定可能です。SQLFetchで1行のみをフェッチするには、prefetch=1を設定します。これは実質的にプリフェッチを無効にします。SQLFetchで2つ以上の行をフェッチするには、フェッチする行の数をプリフェッチに設定します。たとえば、プリフェッチに100を設定するには、次のように入力します。
rc = SQLSetConnectOption(hdbc, TT_PREFETCH_COUNT, 100);プリフェッチ数を0(ゼロ)に設定すると、TimesTenは、データ・ストアに設定した分離レベルに応じて、デフォルトの値を使用します。シリアライズ可能分離モードでは、デフォルトのプリフェッチの値は128です。コミット読取り分離モードでは、デフォルトは5です。デフォルトのプリフェッチの値はほとんどのアプリケーションに最適な設定です。
プリフェッチの値には、0(ゼロ)から128までの任意の整数に再設定できます。プリフェッチ数は再設定できます。シリアライズ可能分離モードが使用されている場合にプリフェッチ数を再設定すると、コミットされるまでロックが設定されます。このため、フェッチと実行の間で遅延が発生した場合は、ロック期間が長くなります。コミット読取り分離モードでは、フェッチが行われるまで読み取られた行のコピーが保持されるため、領域を使用する複数のコピーが存在する場合があります。
プリフェッチを無効にするには、プリフェッチ数を1に設定します。
SQL文の実行がタイムアウトする時間を制御するには、ODBC関数のSQL_QUERY_TIMEOUT (SQLSetStmtOption)またはSQL_QUERY_TIMEOUT (SQLSetConnectOption)を使用します。
TimesTenでは、DSN属性sqlQueryTimeoutを使用して、すべての接続に問合せタイムアウト値を指定できます。DSNにsqlQueryTimeoutを設定すると、その値がTimesTenのその後のすべての接続のデフォルト値になります。接続から継承された可能性があるデフォルト値は、SQL_QUERY_TIMEOUTオプションを指定してSQLSetConnectOptionをコールすると上書きされます。同様に、接続から継承されたデフォルト値は、SQL_QUERY_TIMEOUTオプションを指定してSQLSetStmtOptionをコールすると上書きされます。
SQL_QUERY_TIMEOUTでは、データ・ストアでSQL問合せが実行される制限時間(秒)を指定します。TimesTenでは、タイムアウト・トリガーが起動されると、実行中の問合せに対してタイムアウトが指示されます。タイムアウト・メッセージが問合せに達するまでにタイムラグが発生する可能性あるため、問合せが終了するまでの実際の時間は、タイムアウト・メッセージが問合せに達するまでにかかる時間と指定したタイムアウト値を加算した時間になります。
SQL_QUERY_TIMEOUT機能は、SQL文がアクティブに実行されている場合にのみ動作します。処理のコミット中またはロールバック中にタイムアウトは発生しません。多数のUPDATE、DELETEまたはINSERTを実行するトランザクションでは、コミットまたはロールバックが完了するまでに時間がかかる場合があります。その間、タイムアウト値は無視されます。
アプリケーションでは、カーソルを使用して問合せの結果がスクロールされ、一度に1つの結果行が確認されます。
カーソルの詳細は、『Microsoft ODBC 2.0 Programmer's Reference and SDK Guide』および『Microsoft ODBC 3.0 Software Development Kit and Programmer's Reference』のスクロール可能なカーソルに関する項を参照してください。
ODBC設定では、カーソルは常に結果セットに関連付けられています。この関連付けはODBCドライバで行われますが、アプリケーションでSQLSetStmtOptionなどのコールを使用して、カーソルの特性(1回にフェッチする行数など)を制御できます。問合せの結果を取得する手順は、次のとおりです。
#include <sql.h> SQLHSTMT hstmt; SQLRETURN rc; int i; SQLSMALLINT numCols; SQLCHAR colname[32]; SQLSMALLINT colnamelen, coltype, scale, nullable; SQLULEN collen [MAXCOLS]; SQLLEN outlen [MAXCOLS]; SQLCHAR* data [MAXCOLS]; /* other declarations, and program set-up here */ /* Prepare the SELECT statement */ rc = SQLPrepare(hstmt, (SQLCHAR*) "SELECT * FROM EMP WHERE AGE>20", SQL_NTS); /* ... */ /* Determine number of columns in result rows */ rc = SQLNumResultCols(hstmt, &numCols); /* ... */ /* Describe and bind the columns */ for (i = 0; i < numCols; i++) { rc = SQLDescribeCol(hstmt, (SQLSMALLINT) (i + 1), colname,(SQLSMALLINT)sizeof(colname), &colnamelen, &coltype, &collen[i], &scale, &nullable); /* ... */ data[i] = (UCHAR*) malloc (collen[i] +1); rc = SQLBindCol(hstmt, (SQLSMALLINT) (i + 1), SQL_C_CHAR, data[i], COL_LEN_MAX, &outlen[i]); /* ... */ } /* Execute the SELECT statement */ rc = SQLExecute(hstmt); /* ... */ /* Fetch the rows */ if (numCols > 0) { while ((rc = SQLFetch(hstmt)) == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) { /* ... "Process" the result row */ } /* end of for-loop */ if (rc != SQL_NO_DATA_FOUND) fprintf(stderr, "Unable to fetch the next row\n"); /* Close the cursor associated with the SELECT statement */ rc = SQLFreeStmt(hstmt, SQL_CLOSE); }