Funzione SQLCopyDesc

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

Summary
SQLCopyDesc copia le informazioni sul descrittore da un handle di 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 per un IRD oppure SQLCopyDesc restituirà SQLSTATE HY016 (Non è possibile modificare un descrittore di riga di implementazione).

Restituisce

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 SQL_HANDLE_DESC e Handle di TargetDescHandle. Se nella chiamata è stato passato un SourceDescHandle non valido, SQL_INVALID_HANDLE verrà restituito il valore ma non verrà restituito alcun valore SQLSTATE. La tabella seguente elenca i valori SQLSTATE comunemente restituiti da SQLCopyDesc e ne illustra ognuno nel contesto di questa funzione. la notazione "(DM)" precede le descrizioni di SQLSTATE restituite da Gestione driver. Il codice restituito associato a ogni valore SQLSTATE è SQL_ERROR, se non diversamente specificato.

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

Poiché SQLCopyDesc può essere implementato chiamando SQLGetDescField e SQLSetDescField, SQLCopyDesc può restituire SQLSTATEs restituito 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 Il 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 esiste un SQLSTATE specifico e per il quale non è stato definito 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 funzione (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 il quale 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 in modo asincrono 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 ha 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 Non è stato possibile 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 sui descrittori incoerenti Le informazioni sul descrittore controllate durante una verifica coerenza non erano 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 è stata sospesa a causa di uno stato di transazione sconosciuto. Sono consentite solo le funzioni di disconnessione e di sola lettura. (DM) Per altre informazioni sullo stato sospeso, vedere Funzione SQLEndTran.
HYT01 Timeout della connessione scaduto Il periodo di timeout della connessione è scaduto prima che l'origine dati risponda 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 di applicazione o in un IPD, 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 SQL'istruzione con parametri dinamici e il popolamento automatico dell'IPD è supportato e abilitato, 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, viene copiato il contenuto dei campi originariamente presenti nell'IPD.

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 o meno per il descrittore di destinazione. I campi copiati sovrascrivono i campi esistenti.

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

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

Quando il SQL_DESC_DATA_PTR viene copiato, viene eseguita una verifica coerenza sul descrittore di destinazione. Se la verifica coerenza ha esito negativo, viene restituito SQLSTATE HY021 (informazioni sul descrittore incoerente) e la chiamata a SQLCopyDesc viene immediatamente interrotta. Per altre informazioni sulle verifiche di coerenza, vedere "Verifiche di coerenza" in Funzione SQLSetDescRec.

Gli handle di descrittore possono essere copiati tra le connessioni anche se si verificano 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 campo per campo usando SQLGetDescField e SQLSetDescField.

Quando SQLCopyDesc viene chiamato con sourceDescHandle in un driver e TargetDescHandle in un altro driver, la coda degli 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 di descrittore allocato in modo esplicito a un 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 sullo stesso ConnectionHandle impostando l'attributo dell'istruzione SQL_ATTR_APP_ROW_DESC o SQL_ATTR_APP_PARAM_DESC sull'handle del descrittore allocato in modo esplicito. Al termine, non è necessario chiamare SQLCopyDesc per copiare i valori dei campi del descrittore da un descrittore a un altro. Non è tuttavia possibile associare un handle di descrittore a un StatementHandle in un altro ConnectionHandle. per usare gli stessi valori dei campi di descrizione in StatementHandles in ConnectionHandle diversi, è necessario chiamare SQLCopyDesc.

Per una descrizione dei campi di un'intestazione o di un record di 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 copiarli a livello di applicazione. A tale scopo, l'applicazione associa gli stessi buffer di dati e le stesse informazioni sul descrittore a un'istruzione che recupera i dati e all'istruzione che inserisce i dati in una copia. Questa operazione può essere eseguita condividendo un descrittore dell'applicazione (associando un descrittore allocato in modo esplicito sia come ARD a un'istruzione che come APD in un'altra) o usando SQLCopyDesc per copiare le associazioni tra ARD e APD delle due istruzioni. Se le istruzioni si verificano in connessioni diverse, è necessario usare SQLCopyDesc. È inoltre necessario chiamare SQLCopyDesc per copiare le associazioni tra IRD e l'IPD delle due istruzioni. Quando si esegue la copia tra istruzioni nella stessa connessione, il tipo di informazioni SQL_ACTIVE_STATEMENTS restituito dal driver per una chiamata a SQLGetInfo deve essere maggiore di 1 perché l'operazione riesca. Ciò non si verifica quando si esegue la copia tra connessioni.

Esempio di codice

Nell'esempio seguente le operazioni di descrizione vengono usate per copiare i campi della tabella PartsSource nella tabella PartsCopy. Il contenuto della tabella PartsSource viene recuperato nei buffer del 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 dell'ARD di hstmt0 vengono copiati nei campi dell'APD di hstmt1. Usare SQLSetDescField per impostare l'attributo SQL_DESC_PARAMETER_TYPE dell'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 di descrizione Funzione SQLGetDescRec
Impostazione di un singolo campo descrittore Funzione SQLSetDescField
Impostazione di più campi di descrizione Funzione SQLSetDescRec

Vedere anche

Informazioni di riferimento sulle API ODBC
File di intestazione ODBC