![]() |
図 2 は、初期設定と終了の両方のタスクの関数呼び出しの順序を示しています。図の中央にあるトランザクション処理タスクは、図 3 に示してあります。
初期設定タスクは、環境ハンドルおよび接続ハンドルの割り振りと初期設定から構成されます (これらは後で終了タスクで解放される)。アプリケーションはその後、他の DB2 CLI 関数を呼び出すときに該当するハンドルを渡します。ハンドルとは、DB2 CLI によって制御されるデータ・オブジェクトを参照する変数のことです。ハンドルを使用すると、アプリケーションがグローバル変数またはデータ構造 (IBM の組み込み SQL インターフェースで使用される SQLDA や SQLCA など) を割り振り、管理する必要がなくなります。
SQLAllocHandle() 関数は、ハンドル・タイプおよび親ハンドル引き数とともに呼び出され、環境、接続、ステートメント、または記述子ハンドルを作成します。関数 SQLFreeHandle() は、 1 つのハンドルに割り当てられた資源を解放します。
ハンドルには次の 4 つのタイプがあります。
アプリケーションは、同時に複数のサーバーに接続でき、同じサーバーに複数の別個の接続を確立することもできます。アプリケーションには、データベース・サーバーへの並行接続ごとに 1 つの接続ハンドルが必要です。複数の接続に関する情報は、1 つまたは複数のデータ・ソースへの接続を参照してください。
ユーザーがコネクター・ハンドルの数の限度を設定しているかどうかを判別するには、 SQLGetInfo() を呼び出してください。
記述子および記述子ハンドルは、記述子の使用のセクションで述べます。
1 つまたは複数のデータ・ソースへの並行接続 (または同一データ・ソースへの複数並行接続) をするには、アプリケーションが接続ごとに一度 SQL_HANDLE_DBC の HandleType を指定して、 SQLAllocHandle() を呼び出します。それ以降の接続ハンドルは、SQLConnect() を指定してデータベース接続を要求し、 SQLAllocHandle() と SQL_HANDLE_STMT の HandleType を指定してその接続内で使用されるステートメント・ハンドルを割り振ります。さらに拡張接続関数の SQLDriverConnect() があり、これによって追加の接続オプション、および図形ユーザー・インターフェースをサポートしている環境で接続ダイアログ・ボックスを直接オープンする機能が利用できるようになります。関数 SQLBrowseConnect() を使用すると、データ・ソースに接続するのに必要なすべての属性と属性値を知ることができます。
接続ハンドルを使用すると、スレッドごとに 1 つの接続を利用する複数スレッドのアプリケーションにおいて確実にスレッド保護できます。接続ごとに別々のデータ構造が DB2 CLI によって割り振られ、管理されるからです。
複数サイト更新 (2 フェーズ・コミット) に記述されている分散作業単位接続とは違って、さまざまな接続で実行されるステートメント間で調整は行われません。
/* ... */ #include <stdio.h> #include <stdlib.h> #include <sqlcli1.h> /* ... */ SQLRETURN prompted_connect( SQLHANDLE henv, SQLHANDLE * hdbc); #define MAX_UID_LENGTH 18 #define MAX_PWD_LENGTH 30 #define MAX_CONNECTIONS 2 #define MAX_CONNECTIONS 2 /* extern SQLCHAR server[SQL_MAX_DSN_LENGTH + 1] ; extern SQLCHAR uid[MAX_UID_LENGTH + 1] ; extern SQLCHAR pwd[MAX_PWD_LENGTH + 1] ; */ int main( ) { SQLHANDLE henv; SQLHANDLE hdbc[MAX_CONNECTIONS] ; /* ... */ /* allocate an environment handle */ SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv ) ; /* Connect to first data source */ prompted_connect( henv, &hdbc[0] ) ; /* Connect to second data source */ prompted_connect( henv, &hdbc[1] ) ; /********* Start Processing Step *************************/ /* allocate statement handle, execute statement, etc. */ /********* End Processing Step ***************************/ printf( "\nDisconnecting .....\n" ) ; SQLDisconnect( hdbc[0] ) ; /* disconnect first connection */ SQLDisconnect( hdbc[1] ) ; /* disconnect second connection */ /* free first connection handle */ SQLFreeHandle( SQL_HANDLE_DBC, hdbc[0] ) ; /* free second connection handle */ SQLFreeHandle( SQL_HANDLE_DBC, hdbc[1] ) ; /* free environment handle */ SQLFreeHandle( SQL_HANDLE_ENV, henv ) ; return ( SQL_SUCCESS ) ; } /* prompted_connect - prompt for connect options and connect */ SQLRETURN prompted_connect( SQLHANDLE henv, SQLHANDLE * hdbc ) { SQLCHAR server[SQL_MAX_DSN_LENGTH + 1] ; SQLCHAR uid[MAX_UID_LENGTH + 1] ; SQLCHAR pwd[MAX_PWD_LENGTH + 1] ; /* allocate a connection handle */ if ( SQLAllocHandle( SQL_HANDLE_DBC, henv, hdbc ) != SQL_SUCCESS ) { printf( ">---ERROR while allocating a connection handle-----\n" ) ; return( SQL_ERROR ) ; } /* Set AUTOCOMMIT OFF */ if ( SQLSetConnectAttr( * hdbc, SQL_ATTR_AUTOCOMMIT, ( void * ) SQL_AUTOCOMMIT_OFF, SQL_NTS ) != SQL_SUCCESS ) { printf( ">---ERROR while setting AUTOCOMMIT OFF ------------\n" ) ; return( SQL_ERROR ) ; } printf( ">Enter Server Name:\n" ) ; gets( ( char * ) server ) ; printf( ">Enter User Name:\n" ) ; gets( ( char * ) uid ) ; printf( ">Enter Password:\n" ) ; gets( ( char * ) pwd ) ; if ( SQLConnect( * hdbc, server, SQL_NTS, uid, SQL_NTS, pwd, SQL_NTS ) != SQL_SUCCESS ) { printf( ">--- ERROR while connecting to %s -------------\n", server ) ; SQLDisconnect( * hdbc ) ; SQLFreeHandle( SQL_HANDLE_DBC, * hdbc ) ; return( SQL_ERROR ) ; } else /* Print Connection Information */ printf( "Successful Connect to %s\n", server ) ; return( SQL_SUCCESS ) ; }
次の図は、DB2 CLI アプリケーションでの関数呼び出しの一般的な順序を示しています。関数またはあり得るパスのすべてが示されているわけではありません。
![]() |
図 3 は、トランザクション処理タスクのステップおよび DB2 CLI 関数を示しています。このタスクには次の 5 つのステップがあります。
SQLAllocHandle() は、SQL_HANDLE_STMT の HandleType を指定して呼び出され、ステートメント・ハンドルを割り振ります。ステートメント・ハンドルは、 1 つの SQL ステートメントの実行をトラックするのに使用されるデータ・オブジェクトを参照します。これには、ステートメント属性、SQL ステートメント・テキスト、動的パラメーター、カーソル情報、動的引き数と列のバインド、結果の値、および状況情報 (これらは後で説明します) などの情報が含まれています。各ステートメント・ハンドルは、1 つの接続ハンドルと関連付けられます。
ステートメント・ハンドルは、ステートメントを実行する前に割り振らなければなりません。
一度に割り振れるステートメント・ハンドルの最大数は、システム資源全体によって制限されます (通常は、スタック・サイズ)。しかし、実際に使用されるステートメント・ハンドルの最大数は、DB2 CLI で定義されます。アプリケーションが上記の制限を超えた場合、 SQLPrepare() または SQLExecDirect() の呼び出し時に HY014 SQLSTATE が返されます。
ステートメント・ハンドルがいったん割り振られた後、 SQL ステートメントの指定と実行には 2 つの方法があります。
最初の方法では、ステートメントの準備を実行と分割します。この方法は以下の場合に使用します。
2 番目の方法では、準備ステップと実行ステップを結合します。この方法は以下の場合に使用します。
注: | SQLGetTypeInfo() および第 3 章, 拡張機能の使用に記述されているスキーマ (カタログ) 関数は、独自の照会ステートメントを実行して結果セットを生成します。スキーマ機能を呼び出すということは照会ステートメントを実行するのと同等で、照会ステートメントが実行されたかのように結果セットが処理されます。 |
DB2 ユニバーサル・データベースのバージョン 5 以降では、サーバーにグローバルな動的ステートメント・キャッシュ が保管されています。このキャッシュは、準備状態の SQL ステートメントに対する最も一般的なアクセス・プランを保管するのに使用します。各ステートメントが準備される前に、サーバーはこのキャッシュを検索して、 (このアプリケーションか別のアプリケーション、またはクライアントによって) この SQL ステートメント用のアクセス・プランが作成済みであるかどうかを調べます。作成済みであれば、サーバーが新たにアクセス・プランを生成する必要はなく、代わりに、キャッシュの中にあるものを使用します。現在では、グローバル動的ステートメント・キャッシュのないサーバー (DB2 共通サーバー v2 など) への接続でなければ、アプリケーションがクライアントで接続をキャッシュする必要はありません。クライアントでのキャッシュ接続については、移行のセクションの クライアントでのステートメント・ハンドルのキャッシュを参照してください。
上記のどちらの実行方法でも、 式 (または組み込み SQL のホスト変数) の代わりに、パラメーター・マーカーを使用できます。
パラメーター・マーカーは、'?' 文字で表されるもので、SQL ステートメント内で、ステートメントの実行時にアプリケーション変数の内容が置換される位置を示します。パラメーター・マーカーは、1 を先頭にして左方から右方へ順番に参照されます。ステートメント内のパラメーターの数を判別するのに、 SQLNumParams() を使用することができます。
アプリケーション変数がパラメーター・マーカーに関連付けられるときには、そのパラメーター・マーカーにバインド されます。アプリケーションは SQL ステートメントを実行する前に、アプリケーション変数をそのステートメント内の各パラメーター・マーカーにバインドしなければなりません。バインドは SQLBindParameter() 関数の呼び出しによって実行しますが、その際、指示する引き数の数、パラメーターの数値位置、パラメーターの SQL タイプ、変数のデータ・タイプ、アプリケーション変数を指すポインター、および変数の長さを指定します。
バインドされたアプリケーション変数および関連する長さは、 据え置き 入力引き数と呼ばれます。パラメーターがバインドされるときにはポインターだけが渡されるからです。そのステートメントが実行されるまで変数からデータが読み取られることはありません。アプリケーションは、据え置き引き数を使用すると、バインドされたパラメーター変数の内容を修正したり、新しい値でステートメントを繰り返し実行できるようになります。
各パラメーターの情報は、指定変更されるまでか、またはアプリケーションがパラメーターをアンバインドするかステートメント・ハンドルを除去するまで、そのまま有効です。アプリケーションがパラメーターのバインドを変更せずに SQL ステートメントを繰り返し実行すると、 DB2 CLI は同じポインターを使用して実行時ごとにデータを探し出します。アプリケーションは、パラメーターのバインドを、別の据え置き変数の集まりに変更することもできます。アプリケーションは、据え置き入力フィールドに使用される変数の割り振り解除や廃棄を、フィールドをパラメーター・マーカーにバインドする時と DB2 CLI が実行時にそれらにアクセスする時の間に行うことはできません。
SQL ステートメントが要求するものとは異なるタイプの変数にパラメーターをバインドすることが可能です。アプリケーションはソースの C データ・タイプおよびパラメーター・マーカーの SQL タイプを指示する必要があり、 DB2 CLI は指定された SQL データ・タイプと一致するよう変数の内容を変換します。たとえば、SQL ステートメントには整数値が必要なのに、アプリケーションには整数のストリング表示があるとします。このストリングをパラメーターにバインドすることができ、 DB2 CLI はステートメントの実行時にそのストリングを対応する整数値に変換します。
省略時設定では、DB2 CLI はパラメーター・マーカーのタイプの検査を行いません。アプリケーションが正しくないパラメーター・マーカーのタイプを示すと、 DBMS によって余計な変換が行われるか、エラーになる可能性があります。データ変換の詳細については、データ・タイプとデータ変換を参照してください。
パラメーター・マーカーについての情報は、記述子を使用して見ることができます。実装パラメーター記述子 (implementation parameter descriptor (IPD)) の自動移植を使用可能にした場合、パラメーター・マーカーについての情報が収集されます。ステートメント属性 SQL_ATTR_ENABLE_AUTO_IPD は、この作業では SQL_TRUE に設定する必要があります。詳細については、記述子の使用を参照してください。
パラメーター・マーカーが照会に関する述部の一部であり、ユーザー定義タイプと関連付けられていると、そのパラメーター・マーカーをステートメントの述部部分で組み込みタイプにキャストしなければなりません。そうしないと、エラーが起こります。例については、述部内でのユーザー定義タイプを参照してください。
グローバルな動的ステートメント・キャッシュは、もっと前のセクションで説明されています。アクセス・プランは、ステートメントが厳密に同一である場合、その間でのみ共用されます。パラメーター・マーカー付きの SQL ステートメントの場合、 SQL ステートメントそれ自身が同一であれば、そのパラメーターに結び付いている特定値は、同一である必要はありません。
アプリケーション記憶域をパラメーター・マーカーへバインドする場合のさらに拡張された方法については、下記を参照してください。
ステートメントが実行された後の次のステップは、SQL ステートメントのタイプによって異なります。
ステートメントが照会ステートメントの場合、結果セットの各行を取り出すために通常、次のステップが必要です。
アプリケーションが長いデータの列を小さく分けて取り出す必要がある場合のように、アプリケーションがどの列もバインドしない場合には、 SQLGetData() を使用することができます。バインドされる列とアンバインドされる列がある場合、 SQLBindCol() と SQLGetData() の両方の手法を結合することができます。アプリケーションは、据え置き出力フィールドに使用される変数の割り振り解除や廃棄を、結果セットの列にバインドする時と DB2 CLI がこれらのフィールドにデータを書き込む時の間に行ってはなりません。
SQLBindCol() の呼び出しのときに指定されたデータ・タイプによってデータ変換が指示された場合には、 SQLFetch() の呼び出し時に変換が行われます。説明については、データ・タイプとデータ変換を参照してください。
SQLBindCol() の場合と同様に、ご希望のアプリケーション変数のターゲット C データ・タイプを指定して、データ変換をこの時点でも指示することができます。詳細については、データ・タイプとデータ変換を参照してください。
結果セットの特定の列をアンバインドするには、アプリケーション変数引き数
(TargetValuePtr) にヌル・ポインターを指定して SQLBindCol() を使用してください。
1 回の関数呼び出しですべての列をアンバインドするには、
SQL_UNBIND のオプション を指定して SQLFreeStmt() を使用してください。
列がバインドされている場合は、 SQLGetData() を使用してバインドされていない列として検索する場合にくらべて、一般にアプリケーションのパフォーマンスがよくなります。ただし、アプリケーションは一度に取り出しと処理が可能な長データの量に関して制約される可能性があります。これが考えられる場合は、SQLGetData() の方が良い選択である場合があります。長データを処理する他の手法については、ラージ・オブジェクトの使用を参照してください。
アプリケーション記憶域を結果セット列へバインドする場合のさらに高度な方法については、下記を参照してください。
ステートメントがデータを修正するもの (UPDATE、DELETE または INSERT) である場合、アクションは何も必要ありません。診断メッセージの通常チェックだけが必要です。この場合、SQLRowCount() を使用して、 SQL ステートメントによって影響を受けた行の数を得ることができます。
SQL ステートメントが、定位置 UPDATE または DELETE である場合、 カーソル を使用する必要があります。カーソルとは、活動状態の照会ステートメントの結果表の行を指す、移動可能なポインターです。 (この照会ステートメントには、確実に照会が読み取り専用としてオープンされていないようにするための FOR UPDATE OF 文節が入っていなければなりません。) 組み込み SQL では、カーソル名は行の取り出し、更新、または削除に使用されます。 DB2 CLI では、定位置 UPDATE または DELETE の SQL ステートメントがカーソルを名前で参照する場合に限り、カーソル名が必要です。また、SQLAllocHandle() が、 SQL_HANDLE_STMT の HandleType を指定して呼び出されるときに、カーソル名は自動的に生成されます。
取り出された行を更新するには、アプリケーションが 2 つのステートメント・ハンドルを、 1 つは取り出しに 1 つは更新に使用します。アプリケーションは SQLGetCursorName() を呼び出してカーソル名を獲得します。アプリケーションは定位置 UPDATE または DELETE のテキストをこのカーソル名も含めて生成し、 2 番目のステートメント・ハンドルを使用してその SQL ステートメントを実行します。アプリケーションは、取り出しステートメント・ハンドルを再利用して、定位置 UPDATE または DELETE を実行することはできません。それはまだ使用中だからです。また、SQLSetCursorName() を使用して独自のカーソル名を定義することもできます。ただし、すべてのエラー・メッセージは SQLSetCursorName() で定義された名前ではなく生成された名前を参照するので、生成された名前を使用することをお勧めします。
ステートメントがデータの照会も修正も行わない場合、診断メッセージの通常チェック以外にはアクションは必要ありません。
トランザクション とは、回復可能な 1 つの作業単位、または 1 つのアトミック操作として扱うことができる SQL ステートメントのグループです。このことは、グループ内の全操作は、それらがあたかも単一操作のように完了する (コミットする) またはやり直しする (ロールバックする) ことが保証されているということです。トランザクションを、作業単位または論理作業単位と呼ぶこともあります。トランザクションが複数の接続にわたる場合、それは分散作業単位と呼びます。
DB2 CLI は下記の 2 つのコミット・モードをサポートします。
省略時のコミット・モードは自動コミットです (調整済みトランザクションが関係している場合を除く。 複数サイト更新 (2 フェーズ・コミット) を参照してください)。アプリケーションは SQLSetConnectAttr() を呼び出して、手動コミットと自動コミットのモードを切り替えることができます。一般に、照会専用のアプリケーションは自動コミット・モードにあることが望まれます。データベースに更新を行う必要があるアプリケーションでは、データベース接続が確立されたらすぐに、自動コミットをオフにする必要があります。
同じまたは別のデータベースに複数の接続が存在する場合、個々の接続に独自のトランザクションがあります。必ず意図した接続および関連したトランザクションだけが影響を受けるようにするために、 SQLEndTran() を呼び出す際には正しい接続ハンドルを指定して特に注意して行う必要があります。また、 SQLEndTran() 呼び出しで有効な環境ハンドルおよび NULL 接続ハンドルを指定して、すべての接続をロールバックまたはコミットすることも可能です。分散作業単位接続 (複数サイト更新 (2 フェーズ・コミット) に記述) とは違って、個々の接続に関するトランザクション間で調整は行われません。
アプリケーションが自動コミット・モードである場合、 SQLEndTran() を呼び出す必要は決してありません。各ステートメントの実行の終わりにコミットが暗黙に出されます。
手動コミット・モードでは、SQLDisconnect() を呼び出す前に、 SQLEndTran() を呼び出す必要があります。分散作業単位が関連しているときは、追加規則が適用される場合があります。詳細は、 複数サイト更新 (2 フェーズ・コミット) を参照してください。
更新を実行するアプリケーションが、トランザクションをコミットまたはロールバックする前に切断が行われるまで待つことは、お勧めできません。もう一つの極端な手段は、自動コミット・モードでの操作です。これも、余分な処理が追加されるのでお勧めしません。手動コミットと自動コミット間の切り替えの詳細については、 環境、接続、およびステートメントの属性および SQLSetConnectAttr - 接続属性を設定するを参照してください。
アプリケーションがトランザクションをいつ終了するかを決める際には、下記の点を考慮してください。
トランザクションが終了すると、以下のことが行われます。
詳細および例については、SQLEndTran - 接続のトランザクションの終了を参照してください。
SQLFreeStmt() を呼び出して、特定のステートメント・ハンドルの処理を終了します。この関数は、次のうち 1 つまたは複数を行うのに使用できます。
アプリケーションの行記述子 (ARD) の SQL_DESC_COUNT フィールドも、この場合ゼロにセットされます。記述子の使用法の詳細については、記述子の使用を参照してください。
アプリケーションのパラメーター記述子 (APD) の SQL_DESC_COUNT フィールドも、この場合ゼロにセットされます。記述子の使用法の詳細については、記述子の使用を参照してください。
SQL_HANDLE_STMT の HandleType を指定して SQLFreeHandle() を呼び出し、次のことを行います。
ハンドルを使用して、別の数またはタイプのパラメーターまたは別の結果セットでステートメントを処理するには、その前に必ず列およびパラメーターをアンバインドしてください。そうしないとアプリケーション・プログラミング・エラーが発生する場合があります。
診断とは、アプリケーション内で生成された警告またはエラー条件に対処することです。 DB2 CLI 機能の呼び出し時に戻される診断には、以下の 2 つのレベルがあります。
個々の CLI 関数は基本診断として関数戻りコードを戻します。 SQLGetDiagRec() 関数と SQLGetDiagField() 関数の両方で、さらに詳しい診断情報を通知します。データ・ソースで診断が報告される場合、 SQLGetSQLCA() 関数は SQLCA へアクセスできるようにします。この調整によって、アプリケーションは戻りコードに基づき基本的な制御の流れを扱えるようになり、さらに SQLSTATE により特定の障害原因および特定のエラー処理の判別を可能にします。
SQLGetDiagRec() も SQLGetDiagField() も両方とも、次の 3 つの部分からなる情報を返します。
関数に関する詳細および使用例については、 SQLGetDiagRec - 診断レコードの複数のフィールド設定を取得すると SQLGetDiagField - 診断データのフィールドの入手を参照してください。
SQLGetSQLCA() は特定のフィールドにアクセスするために SQLCA を返しますが、 SQLGetDiagRec() または SQLGetDiagField() の代替として使用されることは決してありません。
次の表に、DB2 CLI 関数の戻りコードをすべてリストします。
第 5 章, DB2 CLI 関数の関数説明のところに、各関数で返される可能性のあるコードをリストしてあります。
戻りコード | 説明 |
---|---|
SQL_SUCCESS | 関数が正常に完了しました。他に利用可能な SQLSTATE 情報はありません。 |
SQL_SUCCESS_WITH_INFO | 関数は正常に完了しましたが、警告または他の情報があります。 SQLGetDiagRec() を呼び出して、 SQLSTATE およびその他の通知メッセージまたは警告を受け取ってください。 SQLSTATE のクラスは '01' です。 SQLState 相互参照表を参照してください。 |
SQL_STILL_EXECUTING | 関数は非同期に実行中で、まだ完了していません。 DB2 CLI ドライバーは、関数を呼び出した後アプリケーションに制御を返しましたが、その関数は実行をまだ完了していません。詳細な説明については、 CLI の非同期実行を参照してください。 |
SQL_NO_DATA_FOUND | 関数が正常に戻りましたが、関連データが見つかりませんでした。 SQL ステートメント実行後に戻されるときは、追加情報が使用可能であり、 SQLGetDiagRec() を呼び出してこれを得ることができます。 |
SQL_NEED_DATA | アプリケーションは SQL ステートメントを実行しようとしましたが、アプリケーションが実行時に渡されるよう指示したパラメーター・データが DB2 CLI にありませんでした。詳細については、長形式データの分割送信 / 取り出しを参照してください。 |
SQL_ERROR | 関数は失敗しました。 SQLGetDiagRec() を呼び出して、 SQLSTATE およびその他のエラー情報を受け取ってください。 |
SQL_INVALID_HANDLE | 関数は無効な入力ハンドル (環境、接続またはステートメント・ハンドル) のために失敗しました。これはプログラミング・エラーです。さらに情報はありません。 |
SQLSTATE は、5 文字 (バイト) の英数字ストリングで、形式は ccsss です (cc はクラスで、sss はサブクラス)。クラスが以下の SQLSTATE は、次のとおりになります。
注: | 前のバージョンの DB2 CLI では、 'HY' ではなく 'S1' のクラスの SQLSTATE を返していました。 CLI ドライバーを指定するには 'S1' の SQLSTATE を返します。そして、アプリケーションは環境属性 SQL_ATTR_ODBC_VERSION を値 SQL_OV_ODBC2 に設定する必要があります。詳細については、SQLSetEnvAttr - 環境属性を設定するおよび付録 B, アプリケーションの移行を参照してください。 |
DB2 CLI の SQLSTATE には、データベース・サーバーによって返される追加の IBM 定義 SQLSTATE と、 ODBC v3 および ISO SQL/CLI 仕様では定義されていない条件に関する DB2 CLI 定義 SQLSTATE の両方が含まれています。これによって、最大量の診断情報が戻されます。また、ODBC 環境でアプリケーションを実行している場合、 ODBC 定義 SQLSTATE を受け取ることも可能です。
アプリケーション内で SQLSTATE を使用する場合、次のガイドラインに従ってください。
注: | SQLSTATE のクラス (先頭 2 文字) に関する依存性を作成すると効果的な場合があります。 |
DB2 CLI によって明示的に返される SQLSTATE のリストと説明は、 SQLState 相互参照表を参照してください。
アプリケーションが DB2 を呼び出す方法 (生じる何らかのエラーも含めて) をより良く理解するには、 CLI/ODBC のトレース機能を使用することができます。 付録 K, DB2 CLI/ODBC/JDBC トレース機能の使用および、 CLI/ODBC 構成キーワード TRACE を参照してください。
組み込みアプリケーションは、SQLCA からすべての診断情報を入手します。 DB2 CLI アプリケーションは SQLGetDiagRec() を使用して同じ情報の大部分を取り出せますが、それでもまだ、ステートメントの処理に関する SQLCA にアクセスする必要が生じる場合があります (たとえば、ステートメントの準備の後、 SQLCA にはそのステートメントの実行に関する相対コストが含まれています)。その前の要求でデータ・ソースとの対話 (たとえば、接続、準備、実行、取り出し、切断) があった場合に限り、SQLCA には意味のある情報が入っています。
SQLGetSQLCA() 関数は、この構造を取り出す場合に使用します。詳細については、SQLGetSQLCA - SQLCA データ構造を入手するを参照してください。
SQLGetSQLCA() は、 SQLGetDiagRec() または SQLGetDiagField() の代替として決して使用すべきではありません。
DB2 CLI アプリケーションを作成するときには、 SQL データ・タイプと C データ・タイプの両方で処理する必要があります。 DBMS は SQL データ・タイプを使用し、アプリケーションは C データ・タイプを使用しなければならないので、これは避けられないことです。そのため、アプリケーションは DBMS とアプリケーションとの間でデータを転送するとき (DB2 CLI 関数を呼び出すとき) に、 C データ・タイプを SQL データ・タイプと突き合わせなければなりません。
これをアドレス指定するのに役立つように、 DB2 CLI はさまざまなデータ・タイプに記号名を付け、 DBMS とアプリケーションとの間のデータ転送を管理します。また、必要に応じてデータ変換 (たとえば、 C 文字ストリングから SQL INTEGER タイプに) も行います。これを実行するには、 DB2 CLI はソースとターゲットの両方のデータ・タイプを認識している必要があります。アプリケーションは記号名を使用して両方のデータ・タイプを識別します。
表 2 では、各 SQL データ・タイプ、それに対応する記号名、および省略時の C 記号名をリストしています。
表 2. SQL 記号データ・タイプおよび省略時データ・タイプ
SQL データ・タイプ | 記号 SQL データ・タイプ | 省略時記号 C データ・タイプ | ||
---|---|---|---|---|
BIGINT | SQL_BIGINT | SQL_C_BIGINT | ||
BLOB | SQL_BLOB | SQL_C_BINARY | ||
BLOB LOCATOR a | SQL_BLOB_LOCATOR | SQL_C_BLOB_LOCATOR | ||
CHAR | SQL_CHAR | SQL_C_CHAR | ||
CHAR FOR BIT DATA b | SQL_BINARY | SQL_C_BINARY | ||
CLOB | SQL_CLOB | SQL_C_CHAR | ||
CLOB LOCATOR a | SQL_CLOB_LOCATOR | SQL_C_CLOB_LOCATOR | ||
DATE | SQL_TYPE_DATE d | SQL_C__TYPE_DATE d | ||
DBCLOB | SQL_DBCLOB | SQL_C_DBCHAR | ||
DBCLOB LOCATOR a | SQL_DBCLOB_LOCATOR | SQL_C_DBCLOB_LOCATOR | ||
DECIMAL | SQL_DECIMAL | SQL_C_CHAR | ||
DOUBLE | SQL_DOUBLE | SQL_C_DOUBLE | ||
FLOAT | SQL_FLOAT | SQL_C_DOUBLE | ||
GRAPHIC | SQL_GRAPHIC | SQL_C_DBCHAR | ||
INTEGER | SQL_INTEGER | SQL_C_LONG | ||
LONG VARCHAR b | SQL_LONGVARCHAR | SQL_C_CHAR | ||
LONG VARCHAR FOR BIT DATA b | SQL_LONGVARBINARY | SQL_C_BINARY | ||
LONG VARGRAPHIC b | SQL_LONGVARGRAPHIC | SQL_C_DBCHAR | ||
NUMERIC c | SQL_NUMERIC c | SQL_C_CHAR | ||
REAL | SQL_REAL | SQL_C_FLOAT | ||
SMALLINT | SQL_SMALLINT | SQL_C_SHORT | ||
TIME | SQL_TYPE_TIME d | SQL_C_TYPE_TIME d | ||
TIMESTAMP | SQL_TYPE_TIMESTAMP d | SQL_C_TYPE_TIMESTAMP d | ||
VARCHAR | SQL_VARCHAR | SQL_C_CHAR | ||
VARCHAR FOR BIT DATA b | SQL_VARBINARY | SQL_C_BINARY | ||
VARGRAPHIC | SQL_VARGRAPHIC | SQL_C_DBCHAR | ||
|
表 3 には、それぞれの記号 C タイプごとに総称型定義を示しています。
C 記号データ・タイプ | C タイプ | 基本 C タイプ | ||
---|---|---|---|---|
SQL_C_CHAR | SQLCHAR | unsigned char | ||
SQL_C_BIT | SQLCHAR | unsigned char または char (値 1 または 0) | ||
SQL_C_TINYINT | SQLSCHAR | signed char (範囲 -128 〜 127) | ||
SQL_C_SHORT | SQLSMALLINT | short int | ||
SQL_C_LONG | SQLINTEGER | long int | ||
SQL_C_DOUBLE | SQLDOUBLE | double | ||
SQL_C_FLOAT | SQLREAL | float | ||
SQL_C_SBIGINT | SQLBIGINT | _int64 | ||
SQL_C_UBIGINT | SQLBIGINT | unsigned _int64 | ||
SQL_C_NUMERIC c | SQL_NUMERIC_STRUCT | 詳細は、表 4 を参照 | ||
SQL_C_TYPE_DATE b | DATE_STRUCT | 詳細は、表 4 を参照 | ||
SQL_C_TYPE_TIME b | TIME_STRUCT | 詳細は、表 4 を参照 | ||
SQL_C_TYPE_TIMESTAMP b | TIMESTAMP_STRUCT | 詳細は、表 4 を参照 | ||
SQL_C_CLOB_LOCATOR a | SQLINTEGER | long int | ||
SQL_C_BINARY | SQLCHAR | unsigned char | ||
SQL_C_BLOB_LOCATOR a | SQLINTEGER | long int | ||
SQL_C_DBCHAR | SQLDBCHAR | wchar_t | ||
SQL_C_DBCLOB_LOCATOR | SQLINTEGER | long int | ||
|
C タイプ | 総称構造 | Windows 構造 |
---|---|---|
DATE_STRUCT |
typedef struct DATE_STRUCT { SQLSMALLINT year; SQLUSMALLINT month; SQLUSMALLINT day; } DATE_STRUCT; |
typedef struct tagDATE_STRUCT { SWORD year; UWORD month; UWORD day; } DATE_STRUCT; |
TIME_STRUCT |
typedef struct TIME_STRUCT { SQLUSMALLINT hour; SQLUSMALLINT minute; SQLUSMALLINT second; } TIME_STRUCT; |
typedef struct tagTIME_STRUCT { UWORD hour; UWORD minutes; UWORD second; } TIME_STRUCT; |
TIMESTAMP_STRUCT |
typedef struct TIMESTAMP_STRUCT { SQLUSMALLINT year; SQLUSMALLINT month; SQLUSMALLINT day; SQLUSMALLINT hour; SQLUSMALLINT minute; SQLUSMALLINT second; SQLINTEGER fraction; } TIMESTAMP_STRUCT; |
typedef struct tagTIMESTAMP_STRUCT { SWORD year; UWORD month; UWORD day; UWORD hour; UWORD minute; UWORD second; UDWORD fraction; } TIMESTAMP_STRUCT; |
SQL_NUMERIC_STRUCT | (なし。Windows 32 ビットのみ) |
typedef struct tagSQL_NUMERIC_STRUCT { SQLCHAR precision; SQLCHAR scale; SQLCHAR sign; a SQLCHAR val[SQL_MAX_NUMERIC_LEN];b c } SQL_NUMERIC_STRUCT; |
SQLUSMALLINT C データ・タイプに関する詳細は、表 5 を参照してください。
|
SQL データ・タイプにマップするデータ・タイプに加えて、ポインターやハンドルなどの他の関数実引き数に使用される C 記号タイプもあります。総称データ・タイプおよび ODBC データ・タイプの両方を次に示します。
定義済み C タイプ | 基本 C タイプ | 一般的な使用法 |
---|---|---|
SQLPOINTER | void * | データおよびパラメーターの記憶域を指すポインター。 |
SQLHANDLE | long int | ハンドル情報の全 4 タイプを参照するハンドル。 |
SQLHENV | long int | 環境情報を参照するハンドル。 |
SQLHDBC | long int | データベース接続情報を参照するハンドル。 |
SQLHSTMT | long int | ステートメント情報を参照するハンドル。 |
SQLUSMALLINT | unsigned short int | 無符号の短整数値用の関数入力引き数。 |
SQLUINTEGER | unsigned long int | 無符号の長整数値用の関数入力引き数。 |
SQLRETURN | short int | DB2 CLI 関数からの戻りコード。 |
バージョン 2.1: 以前のバージョンの DB2 CLI では、次のようになっていました。
|
前述のように、DB2 CLI はアプリケーションと DBMS との間のデータの転送と、必要な変換を管理します。データ転送が実際に行われる前に、ソース、ターゲット、または両方のデータ・タイプが、 SQLBindParameter()、SQLBindCol()、または SQLGetData() の呼び出し時に指示されます。これらの関数は、表 2 に示されている記号タイプの名前を使用して、必要なデータ・タイプを識別します。
たとえば、SQL データ・タイプ DECIMAL(5,3) に対応するパラメーター・マーカーを、アプリケーションの C バッファー・タイプ DOUBLE にバインドする場合、該当する SQLBindParameter() 呼び出しは次のようになります。
SQLBindParameter (hstmt, 1, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_DECIMAL, 5, 3, double_ptr, 0, NULL);
表 2 は、省略時のデータ変換のみを示しています。前の段落で述べた関数を使用して、データを他のタイプに変換することができます。ただし、すべてのデータ変換がサポートされていたり、意味をなすわけではありません。 表 6 は、DB2 CLI がサポートする変換をすべて示しています。
表 6 の最初の列には SQL データ・タイプが入ります。その後の列は C データ・タイプを示しています。 C データ・タイプの列には、次のものが入ります。
例として、CHAR (または表 6 に示されている C 文字ストリング) を SQL_C_LONG (符号付き LONG) へ変換できることが表に示されています。対照的に、LONGVARCHAR は SQL_C_LONG へ変換できません。
必須の形式およびデータ・タイプ間の変換結果については、 付録 F, データ変換を参照してください。
精度と位取りに関する制限に関して SQL 解説書 に指定されている規則、およびタイプ変換に関して切り捨ておよび丸めの規則があります。これらの規則は DB2 CLI に適用されますが、以下の例外があります。すなわち、数値の小数点の右側の値が切り捨てられると切り捨て警告が返され、小数点の左側が切り捨てられるとエラーが返されるというものです。エラーの場合には、アプリケーションが SQLGetDiagRec() を呼び出して SQLSTATE および障害についての追加情報を得る必要があります。浮動小数点データ値をアプリケーションと DB2 CLI 間で移動したり変換する場合、その対応が正確である保証はありません。値が精度および位取りの点で変わる可能性があるからです。
SQL データ・タイプ |
S Q L _ C _ C H A R |
S Q L _ C _ L O N G |
S Q L _ C _ S H O R T |
S Q L _ C _ T I N Y I N T |
|
S Q L _ C _ D O U B L E |
S Q L _ C _ T Y P E _ D A T E |
S Q L _ C _ T Y P E _ T I M E |
S Q L _ C _ T Y P E _ T I M E S T A M P |
S Q L _ C _ B I N A R Y |
S Q L _ C _ B I T |
S Q L _ C _ D B C H A R |
S Q L _ C _ C L O B _ L O C A T O R |
S Q L _ C _ B L O B _ L O C A T O R |
S Q L _ C _ D B C L O B _ L O C A T O R |
S Q L _ C _ B I G I N T |
S Q L _ C _ N U M E R I C | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
BLOB |
X |
|
|
|
|
|
|
|
|
D |
|
|
|
X |
|
|
| ||
CHAR |
D |
X |
X |
X |
X |
X |
X |
X |
X |
X |
X |
|
|
|
|
X |
X | ||
CLOB |
D |
|
|
|
|
|
|
|
|
X |
|
|
X |
|
|
|
| ||
DATE |
X |
|
|
|
|
|
D |
|
X |
|
|
|
|
|
|
|
| ||
DBCLOB |
|
|
|
|
|
|
|
|
|
X |
|
D |
|
|
X |
|
| ||
DECIMAL |
D |
X |
X |
X |
X |
X |
|
|
|
X |
X |
|
|
|
|
X |
X | ||
DOUBLE |
X |
X |
X |
X |
X |
D |
|
|
|
|
X |
|
|
|
|
X |
X | ||
FLOAT |
X |
X |
X |
X |
X |
D |
|
|
|
|
X |
|
|
|
|
X |
X | ||
GRAPHIC |
X |
|
|
|
|
|
|
|
|
|
|
D |
|
|
|
|
| ||
INTEGER |
X |
D |
X |
X |
X |
X |
|
|
|
|
X |
|
|
|
|
X |
X | ||
LONG VARCHAR |
D |
|
|
|
|
|
|
|
|
X |
|
|
|
|
|
|
| ||
LONG VARGRAPHIC |
X |
|
|
|
|
|
|
|
|
X |
|
D |
|
|
|
|
| ||
NUMERIC |
D |
X |
X |
X |
X |
X |
|
|
|
|
X |
|
|
|
|
|
X | ||
REAL |
X |
X |
X |
X |
D |
X |
|
|
|
|
X |
|
|
|
|
|
X | ||
SMALLINT |
X |
X |
D |
X |
X |
X |
|
|
|
|
X |
|
|
|
|
X |
X | ||
BIGINT |
X |
X |
X |
X |
X |
X |
|
|
|
X |
X |
|
|
|
|
D |
X | ||
TIME |
X |
|
|
|
|
|
|
D |
X |
|
|
|
|
|
|
|
| ||
TIMESTAMP |
X |
|
|
|
|
|
X |
X |
D |
|
|
|
|
|
|
|
| ||
VARCHAR |
D |
X |
X |
X |
X |
X |
X |
X |
X |
X |
X |
|
|
|
|
X |
X | ||
VARGRAPHIC |
X |
|
|
|
|
|
|
|
|
|
|
D |
|
|
|
|
| ||
|
以下に示す規則によって、DB2 CLI 関数のストリング引き数の処理のさまざまな面を取り扱います。
入力ストリング引き数には、1 つの関連した長さ引き数があります。この引き数が指示するのは、引き数の正確な長さ (ヌル終止符を除く)、ヌル終了ストリングを示す特殊値 SQL_NTS、または NULL 値を渡す SQL_NULL_DATA のうちのいずれかです。長さを SQL_NTS に設定すると、DB2 CLI はヌル終止符を見つけてストリングの長さを判別します。
出力ストリング引き数には、2 つの関連した長さ引き数があります。 1 つは割り振られる出力バッファーの長さを指定する入力長さ引き数で、もう 1 つは DB2 CLI が返したストリングの実際の長さを返す出力長さ引き数です。戻される長さの値は、戻りに使用できるストリングの全長です。それがバッファーに適合するかどうかとは関係ありません。
SQL 列データの場合、出力がヌルであれば、SQL_NULL_DATA が長さ引き数に戻され、出力バッファーは考慮されません。列の値が NULL 値の場合、記述子フィールド SQL_DESC_INDICATOR_PTR は SQL_NULL_DATA にセットされます。その他のフィールド設定を含む詳細については、 SQLSetDescField() の SQL_DESC_INDICATOR_PTR を参照してください。
出力長さ引き数にヌル・ポインターを指定して関数が呼び出される場合、 DB2 CLI は長さを戻さず、データ・バッファーがデータを保持できる大きさであると想定します。出力データが NULL 値であっても、DB2 CLI はその値が NULL 値であることを示すことはできません。結果セットの列に NULL 値が入る可能性があるときは、出力長さ引き数を指す有効なポインターを必ず指定しなければなりません。有効な出力長さ引き数を必ず使用することを強くお勧めします。
省略時設定では、 DB2 CLI が戻すすべての文字ストリングがヌル終了記号 (16 進数 00) で終わります。ただし、図形および DBCLOB データ・タイプから SQL_C_CHAR アプリケーション変数へ戻されるストリングは除きます。 SQL_C_DBCHAR アプリケーション変数に取り出される図形および DBCLOB データ・タイプは、 2 バイトのヌル終了記号でヌル終了します。このためすべてのバッファーが、予期される最大バイト数にヌル終了記号を加えた値が入る大きさのスペースを割り振る必要があります。
また、SQLSetEnvAttr() を使用し、環境属性を設定して、可変長出力 (文字ストリング) データのヌル終了を使用不能にすることもできます。この場合には、アプリケーションが予期される最長のストリングと同じ長さにバッファーを正確に割り振ります。アプリケーションは、出力長さ引き数の記憶域を指す有効なポインターを与えなければならず、これにより DB2 CLI は戻されるデータの実際の長さを示すことができます。こうしないと、アプリケーションにはこの長さを判別する方法が何もないことになります。 DB2 CLI の省略時は、常にヌル終了記号を書き込むことです。
PATCH1 CLI/ODBC 構成キーワードを使用すると、 DB2 CLI にヌル終了の図形および DBCLOB ストリングを挿入することが可能です。このキーワードは、クライアント構成アシスタント (CCA) によりアクセス可能な CLI/ODBC 設定ノートブックから設定が可能です。 CLI/ODBC アクセスのためのプラットフォーム固有の詳細情報を参照してください。ご使用のプラットフォームの CLI/ODBC ドライバーの構成 セクションには、上記キーワードを設定するのに必要なステップが載せられています。 構成キーワードにある PATCH1 の説明には、図形および DBCLOB ストリングのヌル終了記号を挿入するのに必要な設定を見いだす方法も示されています。
出力ストリングがバッファーに入りきらない場合、 DB2 CLI はバッファーのサイズにストリングを切り捨て、ヌル終了記号を書き込みます。切り捨てが行われると、関数は SQL_SUCCESS_WITH_INFO と、切り捨てを示す SQLSTATE 01004 を戻します。それからアプリケーションはバッファー長と出力長を比較して、どのストリングが切り捨てられたかを判別することができます。
たとえば、SQLFetch() が、 SQL_SUCCESS_WITH_INFO と SQLSTATE 01004 を戻す場合、列にバインドされたバッファーのうちの少なくとも 1 つが小さ過ぎてデータを保持できないということになります。列にバインドされたバッファーごとに、アプリケーションはバッファー長と出力長を比較してどの列が切り捨てられたかを判別できます。
通常、 DB2 CLI はストリング引き数を大文字と小文字の区別をして解釈し、値からスペースをトリムすることはありません。 1 つの例外は、 SQLSetCursorName() 関数のカーソル名の入力引き数です。この場合、カーソル名が区切られ (二重引用符で囲まれ) ないと、前書きおよび後書きブランクが除去され、大文字小文字は無視されます。
アプリケーションが、現行の DB2 CLI ドライバーまたは接続先のデータ・ソースの特性と機能に関する情報を必要とする場合が多くあります。 DB2 CLI には、この情報を戻す関数が多数備わっています。
アプリケーションがこの情報を必要とする状況としては、一般に次の 2 つがあります。
次の DB2 CLI 関数は、データ・ソースの特定情報を提供します。
CLI サンプル ilinfo.c に示されている getinfo.c の例では、 DB2 に接続されている場合に次の出力が発生します。
Server Name: SAMPLE Database Name: SAMPLE Instance Name: db2inst1 DBMS Name: DB2/6000 DBMS Version: 05.00.0000 CLI Driver Name: libdb2.a CLI Driver Version: 05.00.0000 ODBC SQL Conformance Level: Extended Grammar