次の方法で共有


SQLCopyDesc 関数

準拠
導入されたバージョン: ODBC 3.0 標準コンプライアンス: ISO 92

まとめ
SQLCopyDesc は、ある記述子ハンドルから別の記述子ハンドルに記述子情報をコピーします。

構文

  
SQLRETURN SQLCopyDesc(  
     SQLHDESC     SourceDescHandle,  
     SQLHDESC     TargetDescHandle);  

引数

SourceDescHandle
[入力]ソース記述子ハンドル。

TargetDescHandle
[入力]ターゲット記述子ハンドル。 TargetDescHandle 引数には、アプリケーション記述子または IPD へのハンドルを指定できます。 TargetDescHandle を IRD のハンドルに設定できないか 、SQLCopyDesc は SQLSTATE HY016 を返します (実装行記述子を変更できません)。

返品

SQL_SUCCESS、SQL_SUCCESS_WITH_INFO、SQL_ERROR、またはSQL_INVALID_HANDLE。

診断

SQLCopyDesc がSQL_ERRORまたはSQL_SUCCESS_WITH_INFOを返す場合、関連付けられている SQLSTATE 値を取得するには、SQL_HANDLE_DESCの HandleTypeTargetDescHandleハンドルを使用して SQLGetDiagRec を呼び出します。 呼び出しで無効な SourceDescHandle が渡された場合、SQL_INVALID_HANDLEは返されますが、SQLSTATE は返されません。 次の表に、SQLCopyDesc によって一般的に返される SQLSTATE 値を示し、この関数のコンテキストでそれぞれについて説明します。"(DM)" という表記は、ドライバー マネージャーによって返される SQLSTATEs の説明の前にあります。 特に明記されていない限り、各 SQLSTATE 値に関連付けられている戻りコードはSQL_ERROR。

エラーが返されると、SQLCopyDesc呼び出しはすぐに中止され、TargetDescHandle 記述子のフィールドの内容は未定義になります。

SQLCopyDesc は SQLGetDescField と SQLSetDescField を呼び出すことによって実装できるためSQLCopyDesc は SQLGetDescField または SQLSetDescField によって返される SQLSTATEs を返す場合があります。

SQLSTATE エラー 説明
01000 一般的な警告 ドライバー固有の情報メッセージ。 (関数はSQL_SUCCESS_WITH_INFOを返します。
08S01 通信リンクエラー ドライバーとドライバーが接続されたデータ ソース間の通信リンクは、関数の処理が完了する前に失敗しました。
HY000 一般的なエラー 特定の SQLSTATE がなく、実装固有の SQLSTATE が定義されていないエラーが発生しました。 *MessageText バッファー内の SQLGetDiagRec によって返されるエラー メッセージには、エラーとその原因が記述されています。
HY001 メモリ割り当てエラー ドライバーは、関数の実行または完了をサポートするために必要なメモリを割り当てませんでした。
HY007 関連付けられたステートメントが準備されていません SourceDescHandle は IRD に関連付けられていたが、関連付けられたステートメント ハンドルが準備または実行された状態ではなかった。
HY010 関数シーケンス エラー (DM) SourceDescHandle または TargetDescHandle の記述子ハンドルは、非同期実行関数 (この関数ではなく) が呼び出され、この関数が呼び出されたときにまだ実行されていた StatementHandle に関連付られていた。

(DM) SourceDescHandle または TargetDescHandle の記述子ハンドルは、SQLExecute、SQLExecDirectSQLBulkOperationsまたは SQLSetPos が呼び出され、SQL_NEED_DATA返された StatementHandle に関連付けられていた。 この関数は、すべての実行時データ パラメーターまたは列に対してデータが送信される前に呼び出されました。

(DM) SourceDescHandle または TargetDescHandle に関連付けられている接続ハンドルに対して非同期実行関数が呼び出されました。 この非同期関数は、SQLCopyDesc 関数が呼び出されたときにまだ実行されていました。

(DM) SourceDescHandle または TargetDescHandle に関連付けられているステートメント ハンドルの 1 つに対して SQLExecute、SQLExecDirect、または SQLMoreResults が呼び出され、SQL_PARAM_DATA_AVAILABLE返されました。 この関数は、すべてのストリーミング パラメーターのデータが取得される前に呼び出されました。
HY013 メモリ管理エラー メモリが不足している可能性があるため、基になるメモリ オブジェクトにアクセスできなかったため、関数呼び出しを処理できませんでした。
HY016 実装行記述子を変更できません TargetDescHandle が IRD に関連付けられていた。
HY021 一貫性のない記述子情報 整合性チェック中にチェックされた記述子情報に一貫性がありません。 詳細については、SQLSetDescField「整合性チェック」を参照してください。
HY092 無効な属性/オプション識別子 SQLCopyDesc呼び出しによって SQLSetDescField呼び出しが求められたが、TargetDescHandle の FieldIdentifier 引数に対して *ValuePtr が無効でした。
HY117 不明なトランザクション状態のため、接続が中断されます。 切断関数と読み取り専用関数のみが許可されます。 (DM) 中断状態の詳細については、「SQLEndTran 関数」を参照してください
HYT01 接続のタイムアウト データ ソースが要求に応答する前に、接続タイムアウト期間の有効期限が切れています。 接続タイムアウト期間は、SQL_ATTR_CONNECTION_TIMEOUT SQLSetConnectAttr を使用して設定されます。
IM001 ドライバーは、この関数をサポートしていません (DM) SourceDescHandle または TargetDescHandle に関連付けられているドライバーは、関数をサポートしていません。

Comments

SQLCopyDesc呼び出すと、ソース記述子ハンドルのフィールドがターゲット記述子ハンドルにコピーされます。 フィールドは、アプリケーション記述子または IPD にのみコピーでき、IRD にはコピーできません。 フィールドは、アプリケーションまたは実装記述子からコピーできます。

IRD からフィールドをコピーできるのは、ステートメント ハンドルが準備済みまたは実行済み状態の場合のみです。それ以外の場合、関数は SQLSTATE HY007 を返します (Associated ステートメントは準備されていません)。

ステートメントが準備されているかどうかに関係なく、IPD からフィールドをコピーできます。 動的パラメーターを持つ SQL ステートメントが準備されていて、IPD の自動作成がサポートされ、有効になっている場合は、ドライバーによって IPD が設定されます。 IPD を SourceDescHandle として SQLCopyDesc が呼び出されると、設定されたフィールドがコピーされます。 ドライバーによって IPD が設定されていない場合は、最初に IPD 内のフィールドの内容がコピーされます。

記述子のすべてのフィールド (記述子ハンドルが自動的に割り当てられたか明示的に割り当てられたかを指定する) SQL_DESC_ALLOC_TYPEを除き、フィールドが宛先記述子に対して定義されているかどうかに関係なく、コピーされます。 コピーされたフィールドは、既存のフィールドを上書きします。

SourceDescHandle 引数と TargetDescHandle 引数が同じドライバーに関連付けられている場合、ドライバーは、ドライバーが 2 つの異なる接続または環境にある場合でも、すべての記述子フィールドをコピーします。 SourceDescHandle 引数と TargetDescHandle 引数が異なるドライバーに関連付けられている場合、ドライバー マネージャーは ODBC で定義されたフィールドをコピーしますが、記述子の種類に対して ODBC で定義されていないドライバー定義のフィールドはコピーしません。

エラーが発生した場合、SQLCopyDesc呼び出しはすぐに中止されます。

SQL_DESC_DATA_PTR フィールドがコピーされると、ターゲット記述子に対して整合性チェックが実行されます。 整合性チェックが失敗した場合、SQLSTATE HY021 (不整合な記述子情報) が返され、SQLCopyDesc呼び出しはすぐに中止されます。 整合性チェックの詳細については、SQLSetDescRec 関数「整合性チェック」を参照してください。

記述子ハンドルは、接続が異なる環境にある場合でも、接続間でコピーできます。 ドライバー マネージャーは、ソース記述子ハンドルと宛先記述子ハンドルが同じ接続に属していないと検出し、2 つの接続が個別のドライバーに属している場合は、SQLGetDescFieldSQLSetDescField を使用してフィールドごとのコピーを実行することで、SQLCopyDesc を実装します

あるドライバーで SourceDescHandle を使用して SQLCopyDesc を呼び出し、別のドライバーで TargetDescHandle を呼び出すと、SourceDescHandleエラー キューがクリアされます。 これは、この場合、SQLCopyDesc が SQLGetDescField と SQLSetDescField呼び出しによって実装されるために発生します

Note

アプリケーションでは、SQLCopyDesc を呼び出して記述子間でフィールドをコピーするのではなく、明示的に割り当てられた記述子ハンドルを StatementHandle に関連付けることができます。 明示的に割り当てられた記述子は、明示的に割り当てられた記述子のハンドルにSQL_ATTR_APP_ROW_DESCまたはSQL_ATTR_APP_PARAM_DESCステートメント属性を設定することで、同じ ConnectionHandle 上の別の StatementHandle に関連付けることができます。 この操作が完了すると、 記述子フィールドの値を記述子から別の記述子にコピーするために SQLCopyDesc を呼び出す必要はありません。 記述子ハンドルを別の ConnectionHandle の StatementHandle に関連付けることはできません。ただし、異なる ConnectionHandles 上の StatementHandles同じ記述子フィールド値を使用するには、SQLCopyDesc を呼び出す必要があります。

記述子ヘッダーまたはレコード内のフィールドの説明については、「SQLSetDescField 関数」を参照してください。 記述子の詳細については、「記述子」を参照してください

テーブル間での行のコピー

アプリケーションは、アプリケーション レベルでデータをコピーすることなく、あるテーブルから別のテーブルにデータをコピーできます。 これを行うために、アプリケーションは、データをフェッチするステートメントと、データをコピーに挿入するステートメントに、同じデータ バッファーと記述子情報をバインドします。 これを実現するには、アプリケーション記述子を共有するか (明示的に割り当てられた記述子を ARD として 1 つのステートメントにバインドし、APD を別のステートメントでバインドする)、または SQLCopyDesc を使用して 2 つのステートメントの ARD と APD の間のバインディングをコピーします。 ステートメントが異なる接続にある場合は、 SQLCopyDesc を使用する必要があります。 さらに、 2 つのステートメントの IRD と IPD の間のバインディングをコピーするには、SQLCopyDesc を呼び出す必要があります。 同じ接続上のステートメント間でコピーする場合、この操作を成功させるには、SQLGetInfo の呼び出しに対してドライバーによって返されるSQL_ACTIVE_STATEMENTS情報の種類が 1 を超える必要があります。 (これは、複数の接続をコピーする場合には当たりません)。

コード例

次の例では、記述子操作を使用して PartsSource テーブルのフィールドを PartsCopy テーブルにコピーします。 PartsSource テーブルの内容は、hstmt0 の行セット バッファーにフェッチされます。 これらの値は、PartsCopy テーブルの列を設定するために hstmt1INSERT ステートメントのパラメーターとして使用されます。 これを行うには、hstmt0 の IRD のフィールドが hstmt1 の IPD のフィールドにコピーされ、hstmt0 の ARD のフィールドが hstmt1 の APD のフィールドにコピーされます。 SQLSetDescField を使用して、出力パラメーターを含むステートメントから入力パラメーターである必要がある IPD フィールドに IRD フィールドをコピーするときに、IPD のSQL_DESC_PARAMETER_TYPE属性をSQL_PARAM_INPUTに設定します。

#define ROWS 100  
#define DESC_LEN 50  
#define SQL_SUCCEEDED(rc) (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)  
  
// Template for a row  
typedef struct {  
   SQLINTEGER   sPartID;  
   SQLINTEGER   cbPartID;  
   SQLUCHAR     szDescription[DESC_LENGTH];  
   SQLINTEGER   cbDescription;  
   REAL         sPrice;  
   SQLINTEGER   cbPrice;  
} PartsSource;  
  
PartsSource    rget[ROWS];          // rowset buffer  
SQLUSMALLINT   sts_ptr[ROWS];       // status pointer  
SQLHSTMT       hstmt0, hstmt1;  
SQLHDESC       hArd0, hIrd0, hApd1, hIpd1;  
  
// ARD and IRD of hstmt0  
SQLGetStmtAttr(hstmt0, SQL_ATTR_APP_ROW_DESC, &hArd0, 0, NULL);  
SQLGetStmtAttr(hstmt0, SQL_ATTR_IMP_ROW_DESC, &hIrd0, 0, NULL);  
  
// APD and IPD of hstmt1  
SQLGetStmtAttr(hstmt1, SQL_ATTR_APP_PARAM_DESC, &hApd1, 0, NULL);  
SQLGetStmtAttr(hstmt1, SQL_ATTR_IMP_PARAM_DESC, &hIpd1, 0, NULL);  
  
// Use row-wise binding on hstmt0 to fetch rows  
SQLSetStmtAttr(hstmt0, SQL_ATTR_ROW_BIND_TYPE, (SQLPOINTER) sizeof(PartsSource), 0);  
  
// Set rowset size for hstmt0  
SQLSetStmtAttr(hstmt0, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) ROWS, 0);  
  
// Execute a select statement  
SQLExecDirect(hstmt0, "SELECT PARTID, DESCRIPTION, PRICE FROM PARTS ORDER BY 3, 1, 2"",  
               SQL_NTS);  
  
// Bind  
SQLBindCol(hstmt0, 1, SQL_C_SLONG, rget[0].sPartID, 0,   
   &rget[0].cbPartID);  
SQLBindCol(hstmt0, 2, SQL_C_CHAR, &rget[0].szDescription, DESC_LEN,   
   &rget[0].cbDescription);  
SQLBindCol(hstmt0, 3, SQL_C_FLOAT, rget[0].sPrice,   
   0, &rget[0].cbPrice);  
  
// Perform parameter bindings on hstmt1.   
SQLCopyDesc(hArd0, hApd1);  
SQLCopyDesc(hIrd0, hIpd1);  
  
// Set the array status pointer of IRD  
SQLSetStmtAttr(hstmt0, SQL_ATTR_ROW_STATUS_PTR, sts_ptr, SQL_IS_POINTER);  
  
// Set the ARRAY_STATUS_PTR field of APD to be the same  
// as that in IRD.  
SQLSetStmtAttr(hstmt1, SQL_ATTR_PARAM_OPERATION_PTR, sts_ptr, SQL_IS_POINTER);  
  
// Set the hIpd1 records as input parameters  
rc = SQLSetDescField(hIpd1, 1, SQL_DESC_PARAMETER_TYPE, (SQLPOINTER)SQL_PARAM_INPUT, SQL_IS_INTEGER);  
rc = SQLSetDescField(hIpd1, 2, SQL_DESC_PARAMETER_TYPE, (SQLPOINTER)SQL_PARAM_INPUT, SQL_IS_INTEGER);  
rc = SQLSetDescField(hIpd1, 3, SQL_DESC_PARAMETER_TYPE, (SQLPOINTER)SQL_PARAM_INPUT, SQL_IS_INTEGER);  
  
// Prepare an insert statement on hstmt1. PartsCopy is a copy of  
// PartsSource  
SQLPrepare(hstmt1, "INSERT INTO PARTS_COPY VALUES (?, ?, ?)", SQL_NTS);  
  
// In a loop, fetch a rowset, and copy the fetched rowset to PARTS_COPY  
  
rc = SQLFetchScroll(hstmt0, SQL_FETCH_NEXT, 0);  
while (SQL_SUCCEEDED(rc)) {  
  
   // After the call to SQLFetchScroll, the status array has row   
   // statuses. This array is used as input status in the APD  
   // and hence determines which elements of the rowset buffer  
   // are inserted.  
   SQLExecute(hstmt1);  
  
   rc = SQLFetchScroll(hstmt0, SQL_FETCH_NEXT, 0);  
} // while  
情報 参照トピック
複数の記述子フィールドの取得 SQLGetDescRec 関数
単一記述子フィールドの設定 SQLSetDescField 関数
複数の記述子フィールドの設定 SQLSetDescRec 関数

参照

ODBC API リファレンス
ODBC ヘッダー ファイル