Freigeben über


SQLCopyDesc-Funktion

Konformität
Version eingeführt: ODBC 3.0-Normenkonformität: ISO 92

Zusammenfassung
SQLCopyDesc kopiert Deskriptorinformationen von einem Deskriptorhandle in ein anderes.

Syntax

  
SQLRETURN SQLCopyDesc(  
     SQLHDESC     SourceDescHandle,  
     SQLHDESC     TargetDescHandle);  

Argumente

SourceDescHandle
[Eingabe] Quelldeskriptorhandle.

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

Gibt zurück

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR oder SQL_INVALID_HANDLE.

Diagnose

Wenn SQLCopyDesc SQL_ERROR oder SQL_SUCCESS_WITH_INFO zurückgibt, kann ein zugeordneter SQLSTATE-Wert abgerufen werden, indem SQLGetDiagRec mit einem HandleType von SQL_HANDLE_DESC und einem Handle von TargetDescHandle aufgerufen wird. Wenn im Aufruf ein ungültiges SourceDescHandle übergeben wurde, wird SQL_INVALID_HANDLE zurückgegeben, aber es wird kein SQLSTATE zurückgegeben. In der folgenden Tabelle sind die SQLSTATE-Werte aufgeführt, die häufig von SQLCopyDesc zurückgegeben werden, und die einzelnen Werte werden im Kontext dieser Funktion erläutert. die Notation "(DM)" geht den Beschreibungen von SQLSTATEs voran, 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 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 Fehler BESCHREIBUNG
01000 Allgemeine Warnung Treiberspezifische Informationsmeldung. (Die Funktion gibt SQL_SUCCESS_WITH_INFO zurück.)
08S01 Kommunikationslinkfehler Die Kommunikationsverbindung zwischen dem Treiber und der Datenquelle, mit der der Treiber verbunden war, 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 kein implementierungsspezifischer SQLSTATE-Wert definiert wurde. Die von SQLGetDiagRec im *MessageText-Puffer zurückgegebene Fehlermeldung beschreibt den Fehler und seine Ursache.
HY001 Fehler bei der Speicherbelegung Der Treiber konnte den Speicher nicht zuordnen, der für die Unterstützung der Ausführung oder Vervollständigung der Funktion erforderlich ist.
HY007 Zugeordnete Anweisung ist nicht vorbereitet SourceDescHandle war einem IRD zugeordnet, und das zugehörige Anweisungshandle befand sich nicht im vorbereiteten oder ausgeführten Zustand.
HY010 Funktionssequenzfehler (DM) Das Deskriptorhandle in SourceDescHandle oder TargetDescHandle war einem StatementHandle zugeordnet, für den eine asynchron ausgeführte Funktion (nicht diese) aufgerufen wurde und beim Aufruf dieser Funktion weiterhin ausgeführt wurde.

(DM) Das Deskriptorhandle in SourceDescHandle oder TargetDescHandle war 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 der Ausführung 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 eines der Anweisungshandles aufgerufen, die dem 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 Fehler bei der Speicherverwaltung Der Funktionsaufruf konnte nicht verarbeitet werden, da auf die zugrunde liegenden Speicherobjekte nicht zugegriffen werden konnte, möglicherweise aufgrund von niedrigen Speicherbedingungen.
HY016 Ein Implementierungszeilendeskriptor kann nicht geändert werden. TargetDescHandle war einer IRD zugeordnet.
HY021 Inkonsistente Deskriptorinformationen Die bei einer Konsistenzprüfung überprüften Deskriptorinformationen waren nicht konsistent. Weitere Informationen finden Sie unter "Konsistenzprü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 auf TargetDescHandle ungültig.
HY117 Die Verbindung wird aufgrund eines unbekannten Transaktionsstatus angehalten. Nur Trennen und schreibgeschützte Funktionen sind zulässig. (DM) Weitere Informationen zum Angehaltenen Zustand finden Sie unter SQLEndTran-Funktion.
HYT01 Verbindungstimeout abgelaufen Der Zeitraum für das Verbindungstimeout ist abgelaufen, bevor die Datenquelle auf die Anforderung reagiert hat. Der Zeitraum für das Verbindungstimeout wird über SQLSetConnectAttr festgelegt, SQL_ATTR_CONNECTION_TIMEOUT.
IM001 Der Treiber unterstützt diese Funktion nicht. (DM) Der Treiber, der sourceDescHandle oder TargetDescHandle zugeordnet ist, unterstützt die Funktion nicht.

Kommentare

Ein Aufruf von SQLCopyDesc kopiert die Felder des Quelldeskriptorhandles 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 aus einer IRD kopiert werden, wenn sich das Anweisungshandle im vorbereiteten oder ausgeführten Zustand befindet. Andernfalls gibt die Funktion SQLSTATE HY007 (Zugeordnete Anweisung ist nicht vorbereitet) zurück.

Felder können aus einer IPD kopiert werden, unabhängig davon, ob eine Anweisung vorbereitet wurde oder nicht. Wenn eine SQL-Anweisung mit dynamischen Parametern vorbereitet wurde und die automatische Auffüllung 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 aufgefüllten Felder kopiert. Wenn die IPD nicht vom Treiber aufgefüllt wird, werden die Inhalte der felder, die ursprünglich in der IPD enthalten waren, kopiert.

Alle Felder des Deskriptors mit Ausnahme von SQL_DESC_ALLOC_TYPE (der angibt, ob das Deskriptorhandle automatisch oder explizit zugeordnet wurde) werden kopiert, unabhängig davon, ob das Feld für den Zieldeskriptor definiert ist oder nicht. 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 in zwei verschiedenen Verbindungen oder Umgebungen befinden. Wenn die Argumente SourceDescHandle und TargetDescHandle verschiedenen Treibern zugeordnet sind, kopiert der Treiber-Manager von ODBC definierte Felder, kopiert jedoch keine vom Treiber definierten Felder oder Felder, die nicht von ODBC für den Typ des Deskriptors definiert sind.

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

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

Deskriptorhandles können verbindungenübergreifend kopiert werden, auch wenn sich die Verbindungen in unterschiedlichen Umgebungen befinden. Wenn der Treiber-Manager erkennt, dass die Quell- und Zieldeskriptorhandles nicht zu derselben Verbindung gehören und die beiden Verbindungen zu separaten Treibern gehören, implementiert er SQLCopyDesc , indem er eine Feld-für-Feld-Kopie mit SQLGetDescField und SQLSetDescField durchführt.

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 tritt auf, weil SQLCopyDesc in diesem Fall durch Aufrufe von SQLGetDescField und SQLSetDescField implementiert wird.

Hinweis

Eine Anwendung kann einem StatementHandle möglicherweise ein explizit zugeordnetes Deskriptorhandle zuordnen, anstatt SQLCopyDesc aufzurufen, um Felder von einem Deskriptor in eine andere zu kopieren. Ein explizit zugeordneter Deskriptor kann einem anderen StatementHandle auf demselben ConnectionHandle zugeordnet werden, indem das SQL_ATTR_APP_ROW_DESC- oder SQL_ATTR_APP_PARAM_DESC-Anweisungsattribut auf das Handle des explizit zugeordneten Deskriptors festgelegt wird. Wenn dies geschehen ist, muss SQLCopyDesc nicht aufgerufen werden, um Deskriptorfeldwerte von einem Deskriptor in einen anderen zu kopieren. Ein Deskriptorhandle kann jedoch keinem StatementHandle in einem anderen ConnectionHandle zugeordnet werden. Um die gleichen Deskriptorfeldwerte für StatementHandles für verschiedene ConnectionHandles zu verwenden, muss SQLCopyDesc aufgerufen werden.

Eine Beschreibung der Felder in einem Deskriptorheader oder -Datensatz finden Sie unter SQLSetDescField-Funktion. 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 Deskriptorinformationen an eine Anweisung, die die Daten abruft, und die Anweisung, die die Daten in eine Kopie einfügt. Dies kann entweder durch gemeinsame Nutzung eines Anwendungsdeskriptors (Bindung eines explizit zugeordneten Deskriptors als ARD an eine Anweisung und die APD in einer anderen) oder durch Verwenden von SQLCopyDesc zum Kopieren der Bindungen zwischen der ARD und der APD der beiden Anweisungen erreicht werden. Wenn sich die -Anweisungen für unterschiedliche 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 von 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 beim Kopieren zwischen Verbindungen nicht der Fall.)

Codebeispiel

Im folgenden Beispiel werden Deskriptorvorgänge verwendet, um die Felder der Tabelle PartsSource in die Tabelle PartsCopy zu kopieren. Der Inhalt der PartsSource-Tabelle wird in Rowsetpuffer in hstmt0 abgerufen. Diese Werte werden als Parameter einer INSERT-Anweisung auf 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 der 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  
Informationen über Finden Sie unter
Abrufen mehrerer Deskriptorfelder SQLGetDescRec-Funktion
Festlegen eines einzelnen Deskriptorfelds SQLSetDescField-Funktion
Festlegen mehrerer Deskriptorfelder SQLSetDescRec-Funktion

Weitere Informationen

ODBC-API-Referenz
ODBC-Headerdateien