Funzione SQLCopyDesc

Conformità
Versione introdotta: Conformità agli standard ODBC 3.0: ISO 92

Riepilogo
SQLCopyDesc copia le informazioni del descrittore da un handle descrittore a un altro.

Sintassi

  
SQLRETURN SQLCopyDesc(  
     SQLHDESC     SourceDescHandle,  
     SQLHDESC     TargetDescHandle);  

Argomenti

SourceDescHandle
[Input] Handle del descrittore di origine.

TargetDescHandle
[Input] Handle del descrittore di destinazione. L'argomento TargetDescHandle può essere un handle per un descrittore di applicazione o un IPD. TargetDescHandle non può essere impostato su un handle su un IRD o SQLCopyDesc restituirà SQLSTATE HY016 (Non è possibile modificare un descrittore di riga di implementazione).

Valori restituiti

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR o SQL_INVALID_HANDLE.

Diagnostica

Quando SQLCopyDesc restituisce SQL_ERROR o SQL_SUCCESS_WITH_INFO, è possibile ottenere un valore SQLSTATE associato chiamando SQLGetDiagRec con handleType di SQL_HANDLE_DESC e handle di TargetDescHandle. Se è stato passato un oggetto SourceDescHandle non valido nella chiamata, SQL_INVALID_HANDLE verrà restituito ma non verrà restituito sqlSTATE. La tabella seguente elenca i valori SQLSTATE comunemente restituiti da SQLCopyDesc e ne spiega ognuno nel contesto di questa funzione. La notazione "(DM)" precede le descrizioni di SQLSTATEs restituite da Gestione driver. Il codice restituito associato a ogni valore SQLSTATE è SQL_ERROR, a meno che non sia specificato diversamente.

Quando viene restituito un errore, la chiamata a SQLCopyDesc viene interrotta immediatamente e il contenuto dei campi nel descrittore TargetDescHandle non è definito.

Poiché SQLCopyDesc può essere implementato chiamando SQLGetDescField e SQLSetDescField, SQLCopyDesc può restituire SQLSTATEs restituiti da SQLGetDescField o SQLSetDescField.

SQLSTATE Errore Descrizione
01000 Avviso generale Messaggio informativo specifico del driver. (La funzione restituisce SQL_SUCCESS_WITH_INFO.
08S01 Errore del collegamento di comunicazione Collegamento di comunicazione tra il driver e l'origine dati a cui è stato connesso il driver non è riuscito prima del completamento dell'elaborazione della funzione.
HY000 Errore generale: Si è verificato un errore per il quale non è stato specificato SQLSTATE e per il quale non è stato definito alcun SQLSTATE specifico dell'implementazione. Il messaggio di errore restituito da SQLGetDiagRec nel buffer *MessageText descrive l'errore e la relativa causa.
HY001 Errore di allocazione della memoria Il driver non è riuscito ad allocare la memoria necessaria per supportare l'esecuzione o il completamento della funzione.
HY007 Istruzione associata non preparata SourceDescHandle è stato associato a un IRD e l'handle di istruzione associato non era nello stato preparato o eseguito.
HY010 Errore della sequenza di funzioni (DM) L'handle del descrittore in SourceDescHandle o TargetDescHandle è stato associato a un statementHandle per il quale è stata chiamata una funzione in esecuzione asincrona (non questa) ed era ancora in esecuzione quando è stata chiamata questa funzione.

(DM) L'handle del descrittore in SourceDescHandle o TargetDescHandle è stato associato a un statementHandle per cui SQLExecute, SQLExecDirect, SQLBulkOperations o SQLSetPos è stato chiamato e restituito SQL_NEED_DATA. Questa funzione è stata chiamata prima dell'invio dei dati per tutti i parametri o le colonne data-at-execution.

(DM) È stata chiamata una funzione in esecuzione asincrona per l'handle di connessione associato a SourceDescHandle o TargetDescHandle. Questa funzione asincrona era ancora in esecuzione quando è stata chiamata la funzione SQLCopyDesc .

(DM) SQLExecute, SQLExecDirect o SQLMoreResults è stato chiamato per uno degli handle di istruzione associati a SourceDescHandle o TargetDescHandle e restituito SQL_PARAM_DATA_AVAILABLE. Questa funzione è stata chiamata prima del recupero dei dati per tutti i parametri trasmessi.
HY013 Errore di gestione della memoria Impossibile elaborare la chiamata di funzione perché non è stato possibile accedere agli oggetti di memoria sottostanti, probabilmente a causa di condizioni di memoria insufficiente.
HY016 Impossibile modificare un descrittore di riga di implementazione TargetDescHandle è stato associato a un IRD.
HY021 Informazioni sul descrittore incoerente Le informazioni del descrittore controllate durante un controllo coerenza non sono coerenti. Per altre informazioni, vedere "Verifiche di coerenza" in SQLSetDescField.
HY092 Identificatore di attributo/opzione non valido La chiamata a SQLCopyDesc ha richiesto una chiamata a SQLSetDescField, ma *ValuePtr non è valido per l'argomento FieldIdentifier in TargetDescHandle.
HY117 La connessione viene sospesa a causa dello stato sconosciuto della transazione. Sono consentite solo funzioni disconnesse e di sola lettura. (DM) Per altre informazioni sullo stato sospeso, vedere Funzione SQLEndTran.
HYT01 Il timeout della connessione è scaduto Periodo di timeout della connessione scaduto prima che l'origine dati rispondesse alla richiesta. Il periodo di timeout della connessione viene impostato tramite SQLSetConnectAttr, SQL_ATTR_CONNECTION_TIMEOUT.
IM001 Il driver non supporta questa funzione (DM) Il driver associato a SourceDescHandle o TargetDescHandle non supporta la funzione.

Commenti

Una chiamata a SQLCopyDesc copia i campi dell'handle del descrittore di origine nell'handle del descrittore di destinazione. I campi possono essere copiati solo in un descrittore applicazione o in un DP, ma non in un IRD. I campi possono essere copiati da un'applicazione o da un descrittore di implementazione.

I campi possono essere copiati da un IRD solo se l'handle di istruzione si trova nello stato preparato o eseguito; in caso contrario, la funzione restituisce SQLSTATE HY007 (l'istruzione associata non è preparata).

I campi possono essere copiati da un IPD indipendentemente dal fatto che un'istruzione sia stata preparata o meno. Se è stata preparata un'istruzione SQL con parametri dinamici e la popolazione automatica dell'IPD è supportata e abilitata, l'IPD viene popolato dal driver. Quando SQLCopyDesc viene chiamato con l'IPD come SourceDescHandle, i campi popolati vengono copiati. Se l'IPD non viene popolato dal driver, il contenuto dei campi originariamente nell'IPD viene copiato.

Tutti i campi del descrittore, ad eccezione di SQL_DESC_ALLOC_TYPE (che specifica se l'handle del descrittore è stato allocato automaticamente o in modo esplicito), vengono copiati, indipendentemente dal fatto che il campo sia definito per il descrittore di destinazione. I campi copiati sovrascrivono i campi esistenti.

Il driver copia tutti i campi descrittore se gli argomenti SourceDescHandle e TargetDescHandle sono associati allo stesso driver, anche se i driver si trovano in due connessioni o ambienti diversi. Se gli argomenti SourceDescHandle e TargetDescHandle sono associati a driver diversi, Gestione driver copia i campi definiti da ODBC, ma non copia campi definiti dal driver o campi non definiti da ODBC per il tipo di descrittore.

La chiamata a SQLCopyDesc viene interrotta immediatamente se si verifica un errore.

Quando il campo SQL_DESC_DATA_PTR viene copiato, viene eseguita una verifica coerenza nel descrittore di destinazione. Se il controllo di coerenza ha esito negativo, viene restituito SQLSTATE HY021 (informazioni del descrittore incoerente) e la chiamata a SQLCopyDesc viene interrotta immediatamente. Per altre informazioni sui controlli di coerenza, vedere "Verifiche coerenza" nella funzione SQLSetDescRec.

Gli handle del descrittore possono essere copiati tra le connessioni anche se le connessioni si trovano in ambienti diversi. Se Gestione driver rileva che gli handle del descrittore di origine e di destinazione non appartengono alla stessa connessione e le due connessioni appartengono a driver separati, implementa SQLCopyDesc eseguendo una copia da campo per campo usando SQLGetDescField e SQLSetDescField.

Quando SQLCopyDesc viene chiamato con sourceDescHandle in un driver e targetDescHandle in un altro driver, la coda di errori di SourceDescHandle viene cancellata. Ciò si verifica perché SQLCopyDesc in questo caso viene implementato dalle chiamate a SQLGetDescField e SQLSetDescField.

Nota

Un'applicazione potrebbe essere in grado di associare un handle descrittore allocato in modo esplicito a un oggetto StatementHandle, anziché chiamare SQLCopyDesc per copiare i campi da un descrittore a un altro. Un descrittore allocato in modo esplicito può essere associato a un altro StatementHandle nello stesso oggetto ConnectionHandle impostando l'attributo di istruzione SQL_ATTR_APP_ROW_DESC o SQL_ATTR_APP_PARAM_DESC sull'handle del descrittore allocato in modo esplicito. Al termine, SQLCopyDesc non deve essere chiamato per copiare i valori dei campi del descrittore da un descrittore a un altro. Un handle di descrittore non può essere associato a un oggetto StatementHandle in un altro oggetto ConnectionHandle. Per utilizzare gli stessi valori di campo del descrittore in StatementHandles in connectionHandles diversi, è necessario chiamare SQLCopyDesc.

Per una descrizione dei campi in un'intestazione o un record descrittore, vedere Funzione SQLSetDescField. Per altre informazioni sui descrittori, vedere Descrittori.

Copia di righe tra tabelle

Un'applicazione può copiare dati da una tabella a un'altra senza copiare i dati a livello di applicazione. A tale scopo, l'applicazione associa gli stessi buffer di dati e le stesse informazioni del descrittore a un'istruzione che recupera i dati e l'istruzione che inserisce i dati in una copia. A tale scopo, è possibile condividere un descrittore dell'applicazione (associando un descrittore allocato in modo esplicito come ARD a un'istruzione e APD in un'altra) oppure usando SQLCopyDesc per copiare le associazioni tra il ARD e il APD delle due istruzioni. Se le istruzioni si trovano in connessioni diverse, è necessario usare SQLCopyDesc . È inoltre necessario chiamare SQLCopyDesc per copiare le associazioni tra IRD e IPD delle due istruzioni. Quando si copiano istruzioni nella stessa connessione, il tipo di informazioni SQL_ACTIVE_STATEMENTS restituito dal driver per una chiamata a SQLGetInfo deve essere maggiore di 1 affinché l'operazione abbia esito positivo. Questo non è il caso durante la copia tra le connessioni.

Esempio di codice

Nell'esempio seguente vengono usate le operazioni del descrittore per copiare i campi della tabella PartsSource nella tabella PartsCopy. Il contenuto della tabella PartsSource viene recuperato in buffer di set di righe in hstmt0. Questi valori vengono usati come parametri di un'istruzione INSERT in hstmt1 per popolare le colonne della tabella PartsCopy. A tale scopo, i campi dell'IRD di hstmt0 vengono copiati nei campi dell'IPD di hstmt1 e i campi del ARD di hstmt0 vengono copiati nei campi dell'APD di hstmt1. Usare SQLSetDescField per impostare l'attributo SQL_DESC_PARAMETER_TYPE IPD su SQL_PARAM_INPUT quando si copiano campi IRD da un'istruzione con parametri di output in campi IPD che devono essere parametri di 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  
Per informazioni su Vedere
Recupero di più campi descrittore Funzione SQLGetDescRec
Impostazione di un singolo campo descrittore Funzione SQLSetDescField
Impostazione di più campi descrittori Funzione SQLSetDescRec

Vedi anche

Riferimento API ODBC
File di intestazione ODBC