Teilen über


SQLCopyDesc-Funktion

Konformität
Version eingeführt: ODBC 3.0 Standards Compliance: ISO 92

Zusammenfassung
SQLCopyDesc kopiert Deskriptorinformationen von einem Beschreibungshandle in ein anderes.

Syntax

  
SQLRETURN SQLCopyDesc(  
     SQLHDESC     SourceDescHandle,  
     SQLHDESC     TargetDescHandle);  

Argumente

SourceDescHandle
[Eingabe] Quelldeskriptorhandle.

TargetDescHandle
[Eingabe] Zieldeskriptorhandle. Das Argument TargetDescHandle kann ein Handle für einen Anwendungsdeskriptor oder eine IPD sein. TargetDescHandle kann nicht auf ein Handle auf eine IRD festgelegt werden, oder SQLCopyDesc gibt SQLSTATE HY016 zurück (Ein Implementierungszeilendeskriptor kann nicht geändert werden).

Gibt zurück

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR oder SQL_INVALID_HANDLE.

Diagnostik

Wenn SQLCopyDesc SQL_ERROR oder SQL_SUCCESS_WITH_INFO zurückgibt, kann ein zugeordneter SQLSTATE-Wert durch Aufrufen von SQLGetDiagRec mit einem HandleType von SQL_HANDLE_DESC und einem Handle of TargetDescHandle abgerufen werden. Wenn ein ungültiger SourceDescHandle-Wert im Aufruf übergeben wurde, wird SQL_INVALID_HANDLE zurückgegeben, aber es wird kein SQLSTATE-Wert zurückgegeben. In der folgenden Tabelle sind die SQLSTATE-Werte aufgeführt, die häufig von SQLCopyDesc zurückgegeben werden, und jede wird im Kontext dieser Funktion erläutert. Die Notation "(DM)" steht vor den Beschreibungen von SQLSTATEs, die vom Treiber-Manager zurückgegeben werden. Der rückgabecode, der jedem SQLSTATE-Wert zugeordnet ist, ist SQL_ERROR, sofern nicht anders angegeben.

Wenn ein Fehler zurückgegeben wird, wird der Aufruf von SQLCopyDesc sofort abgebrochen, und der Inhalt der Felder im TargetDescHandle-Deskriptor ist nicht definiert.

Da SQLCopyDesc möglicherweise durch Aufrufen von SQLGetDescField und SQLSetDescField implementiert werden kann, gibt SQLCopyDesc möglicherweise SQLSTATEs zurück, die von SQLGetDescField oder SQLSetDescField zurückgegeben werden.

SQLSTATE Error Beschreibung
01000 Allgemeiner Warnhinweis Treiberspezifische Informationsmeldung. (Funktion gibt SQL_SUCCESS_WITH_INFO zurück.)
08S01 Kommunikationslinkfehler Die Kommunikationsverbindung zwischen dem Treiber und der Datenquelle, mit der der Treiber verbunden wurde, ist fehlgeschlagen, bevor die Verarbeitung der Funktion abgeschlossen wurde.
HY000 Allgemeiner Fehler Es ist ein Fehler aufgetreten, für den kein spezifischer SQLSTATE-Wert vorhanden war und für den keine implementierungsspezifische SQLSTATE definiert wurde. Die von SQLGetDiagRec im *MessageText-Puffer zurückgegebene Fehlermeldung beschreibt den Fehler und dessen Ursache.
HY001 Speicherzuweisungsfehler Der Treiber konnte den erforderlichen Arbeitsspeicher nicht zuordnen, um die Ausführung oder den Abschluss der Funktion zu unterstützen.
HY007 Die zugeordnete Anweisung ist nicht vorbereitet. SourceDescHandle wurde einem IRD zugeordnet, und der zugehörige Anweisungshandle befand sich nicht im vorbereiteten oder ausgeführten Zustand.
HY010 Funktionssequenzfehler (DM) Das Deskriptorhandle in SourceDescHandle oder TargetDescHandle wurde einem StatementHandle zugeordnet, für das eine asynchron ausgeführte Funktion (nicht diese) aufgerufen wurde und noch ausgeführt wurde, als diese Funktion aufgerufen wurde.

(DM) Das Deskriptorhandle in SourceDescHandle oder TargetDescHandle wurde einem StatementHandle zugeordnet, für das SQLExecute, SQLExecDirect, SQLBulkOperations oder SQLSetPos aufgerufen und SQL_NEED_DATA zurückgegeben wurde. Diese Funktion wurde aufgerufen, bevor Daten für alle Daten bei ausführungsparametern oder -spalten gesendet wurden.

(DM) Eine asynchron ausgeführte Funktion wurde für das Verbindungshandle aufgerufen, das dem SourceDescHandle oder TargetDescHandle zugeordnet ist. Diese asynchrone Funktion wurde noch ausgeführt, als die SQLCopyDesc-Funktion aufgerufen wurde.

(DM) SQLExecute, SQLExecDirect oder SQLMoreResults wurde für eine der Anweisungshandles aufgerufen, die der SourceDescHandle- oder TargetDescHandle zugeordnet sind und SQL_PARAM_DATA_AVAILABLE zurückgegeben wurden. Diese Funktion wurde aufgerufen, bevor Daten für alle gestreamten Parameter abgerufen wurden.
HY013 Speicherverwaltungsfehler Der Funktionsaufruf konnte nicht verarbeitet werden, da auf die zugrunde liegenden Speicherobjekte nicht zugegriffen werden konnte, möglicherweise aufgrund geringer Arbeitsspeicherbedingungen.
HY016 Ein Implementierungszeilendeskriptor kann nicht geändert werden. TargetDescHandle wurde einer IRD zugeordnet.
HY021 Inkonsistente Beschreibungsinformationen Die während einer Konsistenzüberprüfung überprüften Deskriptorinformationen waren nicht konsistent. Weitere Informationen finden Sie unter "Konsistenzüberprüfungen" in SQLSetDescField.
HY092 Ungültiger Attribut-/Optionsbezeichner Der Aufruf von SQLCopyDesc hat einen Aufruf von SQLSetDescField aufgefordert, aber *ValuePtr war für das FieldIdentifier-Argument für TargetDescHandle ungültig.
HY117 Die Verbindung wird aufgrund des unbekannten Transaktionsstatus angehalten. Es sind nur Trenn- und schreibgeschützte Funktionen zulässig. (DM) Weitere Informationen zum angehaltenen Zustand finden Sie unter SQLEndTran Function.
HYT01 Verbindungstimeout abgelaufen Der Zeitraum für das Verbindungstimeout ist abgelaufen, bevor die Datenquelle auf die Anforderung geantwortet hat. Der Verbindungstimeoutzeitraum wird über SQLSetConnectAttr SQL_ATTR_CONNECTION_TIMEOUT festgelegt.
IM001 Dieser Treiber unterstützt diese Funktion nicht. (DM) Der dem SourceDescHandle- oder TargetDescHandle zugeordnete Treiber unterstützt die Funktion nicht.

Kommentare

Ein Aufruf von SQLCopyDesc kopiert die Felder des Quelldeskriptorshandle in das Zieldeskriptorhandle. Felder können nur in einen Anwendungsdeskriptor oder eine IPD, aber nicht in eine IRD kopiert werden. Felder können aus einer Anwendung oder einem Implementierungsdeskriptor kopiert werden.

Felder können nur dann aus einer IRD kopiert werden, wenn sich der Anweisungshandle im vorbereiteten oder ausgeführten Zustand befindet. andernfalls gibt die Funktion SQLSTATE HY007 zurück (Associated-Anweisung ist nicht vorbereitet).

Felder können aus einer IPD kopiert werden, unabhängig davon, ob eine Anweisung vorbereitet wurde. Wenn eine SQL-Anweisung mit dynamischen Parametern vorbereitet und die automatische Population der IPD unterstützt und aktiviert wird, wird die IPD vom Treiber aufgefüllt. Wenn SQLCopyDesc mit der IPD als SourceDescHandle aufgerufen wird, werden die ausgefüllten Felder kopiert. Wenn die IPD nicht vom Treiber aufgefüllt wird, werden die Inhalte der felder, die ursprünglich in der IPD enthalten sind, kopiert.

Alle Felder des Deskriptors, mit Ausnahme von SQL_DESC_ALLOC_TYPE (die angibt, ob der Deskriptorhandle automatisch oder explizit zugewiesen wurde) werden kopiert, unabhängig davon, ob das Feld für den Zieldeskriptor definiert ist. Kopierte Felder überschreiben die vorhandenen Felder.

Der Treiber kopiert alle Deskriptorfelder, wenn die Argumente SourceDescHandle und TargetDescHandle demselben Treiber zugeordnet sind, auch wenn sich die Treiber auf zwei verschiedenen Verbindungen oder Umgebungen befinden. Wenn die Argumente SourceDescHandle und TargetDescHandle unterschiedlichen Treibern zugeordnet sind, kopiert der Treiber-Manager ODBC-definierte Felder, kopiert jedoch keine treiberdefinierten Felder oder Felder, die von ODBC für den Deskriptortyp nicht definiert sind.

Der Aufruf von SQLCopyDesc wird sofort abgebrochen, wenn ein Fehler auftritt.

Wenn das feld SQL_DESC_DATA_PTR kopiert wird, wird eine Konsistenzüberprüfung für den Zieldeskriptor durchgeführt. Wenn die Konsistenzüberprüfung fehlschlägt, wird SQLSTATE HY021 (Inkonsistente Beschreibungsinformationen) zurückgegeben, und der Aufruf von SQLCopyDesc wird sofort abgebrochen. Weitere Informationen zu Konsistenzprüfungen finden Sie unter "Konsistenzüberprüfungen" in der SQLSetDescRec-Funktion.

Deskriptorhandles können über Verbindungen hinweg kopiert werden, auch wenn sich die Verbindungen in unterschiedlichen Umgebungen befinden. Wenn der Treiber-Manager erkennt, dass die Quell- und Zieldeskriptorhandles nicht zur gleichen Verbindung gehören und die beiden Verbindungen zu separaten Treibern gehören, implementiert er SQLCopyDesc durch Ausführen einer Feldkopie mit SQLGetDescField und SQLSetDescField.

Wenn SQLCopyDesc mit einem SourceDescHandle auf einem Treiber und einem TargetDescHandle auf einem anderen Treiber aufgerufen wird, wird die Fehlerwarteschlange der SourceDescHandle gelöscht. Dies geschieht, da SQLCopyDesc in diesem Fall durch Aufrufe von SQLGetDescField und SQLSetDescField implementiert wird.

Hinweis

Eine Anwendung kann möglicherweise ein explizit zugewiesenes Deskriptorhandle einem StatementHandle zuordnen, anstatt SQLCopyDesc aufzurufen, um Felder von einem Deskriptor in einen anderen zu kopieren. Ein explizit zugewiesener Deskriptor kann einem anderen StatementHandle auf demselben ConnectionHandle zugeordnet werden, indem das attribut SQL_ATTR_APP_ROW_DESC oder SQL_ATTR_APP_PARAM_DESC Anweisung auf das Handle des explizit zugewiesenen Deskriptors festgelegt wird. Wenn dies geschieht, muss SQLCopyDesc nicht aufgerufen werden, um Deskriptorfeldwerte von einem Deskriptor in einen anderen zu kopieren. Ein Deskriptorhandle kann keinem StatementHandle für ein anderes ConnectionHandle zugeordnet werden. Um jedoch dieselben Deskriptorfeldwerte für StatementHandles auf verschiedenen ConnectionHandles zu verwenden, muss SQLCopyDesc aufgerufen werden.

Eine Beschreibung der Felder in einem Beschreibungsheader oder Datensatz finden Sie unter SQLSetDescField Function. Weitere Informationen zu Deskriptoren finden Sie unter Deskriptoren.

Kopieren von Zeilen zwischen Tabellen

Eine Anwendung kann Daten aus einer Tabelle in eine andere kopieren, ohne die Daten auf Anwendungsebene zu kopieren. Dazu bindet die Anwendung dieselben Datenpuffer und Beschreibungsinformationen an eine Anweisung, die die Daten abruft, und die Anweisung, die die Daten in eine Kopie einfügt. Dies kann entweder durch die Freigabe eines Anwendungsdeskriptors (binden Sie einen explizit zugewiesenen Deskriptor als ard an eine Anweisung und die APD in einer anderen) oder mithilfe von SQLCopyDesc , um die Bindungen zwischen der ARD und der APD der beiden Anweisungen zu kopieren. Wenn sich die Anweisungen auf unterschiedlichen Verbindungen befinden, muss SQLCopyDesc verwendet werden. Darüber hinaus muss SQLCopyDesc aufgerufen werden, um die Bindungen zwischen der IRD und der IPD der beiden Anweisungen zu kopieren. Beim Kopieren über Anweisungen in derselben Verbindung muss der vom Treiber für einen Aufruf von SQLGetInfo zurückgegebene SQL_ACTIVE_STATEMENTS Informationstyp größer als 1 sein, damit dieser Vorgang erfolgreich ausgeführt werden kann. (Dies ist nicht der Fall beim Kopieren über Verbindungen.)

Codebeispiel

Im folgenden Beispiel werden Deskriptorvorgänge verwendet, um die Felder der PartsSource-Tabelle in die PartsCopy-Tabelle zu kopieren. Der Inhalt der PartsSource-Tabelle wird in Rowsetpuffer in hstmt0 abgerufen. Diese Werte werden als Parameter einer INSERT-Anweisung in hstmt1 verwendet, um die Spalten der PartsCopy-Tabelle aufzufüllen. Dazu werden die Felder der IRD von hstmt0 in die Felder der IPD von hstmt1 kopiert, und die Felder der ARD von hstmt0 werden in die Felder der APD von hstmt1 kopiert. Verwenden Sie SQLSetDescField , um das SQL_DESC_PARAMETER_TYPE-Attribut des IPD auf SQL_PARAM_INPUT festzulegen, wenn Sie IRD-Felder aus einer Anweisung mit Ausgabeparametern in IPD-Felder kopieren, die Eingabeparameter sein müssen.

#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  
Weitere Informationen zu Siehe
Abrufen mehrerer Deskriptorfelder SQLGetDescRec-Funktion
Festlegen eines einzelnen Deskriptorfelds SQLSetDescField-Funktion
Festlegen mehrerer Deskriptorfelder SQLSetDescRec-Funktion

Weitere Informationen

ODBC-API-Referenz
ODBC-Headerdateien