FUNKCE SQLCopyDesc

Soulad
Představená verze: ODBC 3.0 Shoda s normami: ISO 92

Shrnutí
SQLCopyDesc kopíruje informace o deskriptoru z jednoho handle deskriptoru na druhý.

Syntax

  
SQLRETURN SQLCopyDesc(  
     SQLHDESC     SourceDescHandle,  
     SQLHDESC     TargetDescHandle);  

Arguments

SourceDescHandle
[Vstup] Zdrojový deskriptor přezdívka.

TargetDescHandle
[Vstup] Handle deskriptoru cíle. Argument TargetDescHandle může být handle aplikačního deskriptoru nebo IPD. TargetDescHandle nelze nastavit na handle pro IRD, nebo SQLCopyDesc vrátí SQLSTATE HY016 (nelze upravit deskriptor řádku implementace).

Returns

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR nebo SQL_INVALID_HANDLE.

Diagnostics

Když SQLCopyDesc vrací SQL_ERROR nebo SQL_SUCCESS_WITH_INFO, lze získat přidruženou hodnotu SQLstate voláním SQLGetDiagRec s HandleType SQL_HANDLE_DESC a HandlemTargetDescHandle. Pokud byl ve volání předán neplatný SourceDescHandle , SQL_INVALID_HANDLE se vrátí, ale SQLSTATE se nevrátí. Následující tabulka uvádí hodnoty SQLSTATE, které SQLCopyDesc běžně vrací, a vysvětluje každou z nich v kontextu této funkce; notace "(DM)" předchází popisům SQLstavů vráceným Správcem ovladačů. Návratový kód přidružený ke každé hodnotě SQLSTATE je SQL_ERROR, pokud není uvedeno jinak.

Když je chyba vrácena, volání SQLCopyDesc je okamžitě přerušeno a obsah polí v deskriptoru TargetDescHandle zůstává nedefinovaný.

Protože SQLCopyDesc lze implementovat voláním SQLGetDescField a SQLSetDescField, může SQLCopyDesc vracet SQLSTATES vrácené SQLGetDescField nebo SQLSetDescField.

SQLSTATE Error Description
01000 Obecné upozornění Informační zpráva specifická pro řidiče (Funkce vrátí SQL_SUCCESS_WITH_INFO.)
08S01 Selhání komunikačního propojení Komunikační propojení mezi ovladačem a zdrojem dat, ke kterému byl ovladač připojen, selhalo před dokončením zpracování funkce.
HY000 Obecná chyba Došlo k chybě, pro kterou nebyla definována žádná specifická funkce SQLSTATE a pro kterou nebyla definována žádná implementace sqlSTATE. Chybová zpráva vrácená nástrojem SQLGetDiagRec v vyrovnávací paměti *MessageText popisuje chybu a její příčinu.
HY001 Chyba přidělení paměti Ovladač nebyl schopen přidělit paměť potřebnou k podpoře nebo dokončení funkce.
HY007 Související prohlášení není připraveno SourceDescHandle byl spojen s IRD a příslušný příkazový handle nebyl ve stavu připravenosti ani vykonání.
HY010 Chyba posloupnosti funkcí (DM) Descriptor handle v SourceDescHandle nebo TargetDescHandle byl spojen s StatementHandle , pro který byla volána asynchronně vykonávající funkce (ne tato) a stále se spouštěla, když byla tato funkce vyvolána.

(DM) Handle deskriptoru v SourceDescHandle nebo TargetDescHandle byl spojen s StatementHandle , pro který byly volány a vracely se SQLExecute, SQLExecDirect, SQLBulkOperations nebo SQLSetPos a vracely SQL_NEED_DATA. Tato funkce byla volána před odesláním dat pro všechny parametry provádění dat nebo sloupce.

(DM) Byla volána asynchronně vykonávající funkce pro handle spojení, která je spojena se SourceDescHandle nebo TargetDescHandle. Tato asynchronní funkce se stále vykonávala, když byla volána funkce SQLCopyDesc .

(DM) SQLExecute, SQLExecDirect nebo SQLMoreResults byl vyvolán pro jeden z příkazových rukojeti spojených se SourceDescHandle nebo TargetDescHandle a vrátil SQL_PARAM_DATA_AVAILABLE. Tato funkce byla volána před načtením dat pro všechny streamované parametry.
HY013 Chyba správy paměti Volání funkce nelze zpracovat, protože základní objekty paměti nelze získat přístup, pravděpodobně kvůli nedostatku paměti.
HY016 Nelze upravovat deskriptor řádku implementace TargetDescHandle byl spojen s IRD.
HY021 Nekonzistentní informace o popisech Informace o popisu kontrolované během kontroly konzistence nebyly konzistentní. Pro více informací viz "Kontroly konzistence" v SQLSetDescField.
HY092 Neplatný identifikátor atributu/opce Volání na SQLCopyDesc vyvolalo volání na SQLSetDescField, ale *ValuePtr nebyl platný pro argument FieldIdentifier na TargetDescHandle.
HY117 Připojení je pozastaveno kvůli neznámému stavu transakce. Jsou povoleny pouze funkce pro odpojení a jen pro čtení. (DM) Další informace o pozastaveném stavu naleznete v tématu FUNKCE SQLEndTran.
HYT01 Vypršel časový limit připojení Platnost časového limitu připojení vypršela, než zdroj dat odpověděl na žádost. Časový limit připojení je nastavený prostřednictvím sqlSetConnectAttr SQL_ATTR_CONNECTION_TIMEOUT.
IM001 Ovladač tuto funkci nepodporuje. (DM) Ovladač přiřazený k SourceDescHandle nebo TargetDescHandle tuto funkci nepodporuje.

Comments

Volání do SQLCopyDesc zkopíruje pole ze zdrojového deskriptoru na cílový descriptor. Pole se dají kopírovat jenom do popisovače aplikace nebo IPD, ale ne do IRD. Pole lze kopírovat buď z aplikace, nebo z implementačního deskriptoru.

Pole lze z IRD zkopírovat pouze tehdy, pokud je handle příkazu ve stavu připravený nebo vykonáný; jinak funkce vrací SQLSTATE HY007 (přidružený příkaz není připraven).

Pole lze kopírovat z IPD, ať už bylo prohlášení připraveno nebo ne. Pokud byl připraven SQL příkaz s dynamickými parametry a automatické zapopulování IPD je podporováno a povoleno, IPD je vyplněn ovladačem. Když je SQLCopyDesc volán s IPD jako SourceDescHandle, vyplněná pole jsou zkopírována. Pokud IPD není ovladačem vyplněno, zkopíruje se obsah polí původně v IPD.

Všechna pole deskriptoru, kromě SQL_DESC_ALLOC_TYPE (který určuje, zda byl handle deskriptoru automaticky nebo explicitně přidělen), jsou kopírována, bez ohledu na to, zda je pole definováno pro cílový deskriptor, nebo ne. Zkopírovaná pole přepíší existující pole.

Ovladač zkopíruje všechna pole deskriptoru, pokud jsou argumenty SourceDescHandle a TargetDescHandle spojeny se stejným ovladačem, i když jsou ovladače na dvou různých připojeních nebo prostředích. Pokud jsou argumenty SourceDescHandle a TargetDescHandle přiřazeny k různým ovladačům, správce ovladačů kopíruje pole definovaná ODBC, ale nekopíruje pole definovaná ovladačem nebo pole, která nejsou definována ODBC pro typ deskriptoru.

Volání na SQLCopyDesc je okamžitě přerušeno, pokud dojde k chybě.

Když je pole SQL_DESC_DATA_PTR zkopírováno, provádí se kontrola konzistence cílového deskriptoru. Pokud kontrola konzistence selže, vrátí se SQLSTATE HY021 (Inconsistent descriptor information) a volání na SQLCopyDesc je okamžitě ukončeno. Pro více informací o kontrolách konzistence viz "Kontroly konzistence" ve funkci SQLSetDescRec.

Handle deskriptorů lze kopírovat napříč spojeními, i když jsou tato spojení v různých prostředích. Pokud správce ovladačů zjistí, že zdrojová a cílová deskriptorová zpracování nepatří ke stejnému spojení a obě spojení patří do samostatných ovladačů, implementuje SQLCopyDesc tím, že provede kopírovaní pole po poli pomocí SQLGetDescField a SQLSetDescField.

Když je SQLCopyDesc volán s SourceDescHandle na jednom ovladači a TargetDescHandle na jiném ovladači, chybová fronta SourceDescHandle je vymazána. K tomu dochází proto, že SQLCopyDesc je v tomto případě implementován voláním SQLGetDescField a SQLSetDescField.

Note

Aplikace může být schopna přiřadit explicitně přidělený handle deskriptoru s StatementHandlem, místo aby volala SQLCopyDesc pro kopírování polí z jednoho deskriptoru do druhého. Explicitně přidělený deskriptor může být přiřazen k jinému CommandHandle na stejném ConnectionHandle nastavením atributu SQL_ATTR_APP_ROW_DESC nebo SQL_ATTR_APP_PARAM_DESC příkazu na handle explicitně přiděleného deskriptoru. Když je to provedeno, nemusí být volán SQLCopyDesc , aby kopíroval hodnoty polí deskriptoru z jednoho deskriptoru do druhého. Descriptor handle však nemůže být přiřazen k CommandHandle na jiném ConnectionHandle; pro použití stejných hodnot polí descriptoru na CommandHandles na různých ConnectionHandles je nutné volat SQLCopyDesc .

Pro popis polí v hlavičce nebo záznamu deskriptoru viz SQLSetDescField Function. Pro více informací o popisech viz Descriptors.

Kopírování řádků mezi tabulkami

Aplikace může kopírovat data z jedné tabulky do druhé, aniž by je kopírovala na úrovni aplikace. K tomu aplikace připojí stejné datové buffery a informace o deskriptoru na příkaz, který data načítá, a na příkaz, který data vloží do kopie. Toho lze dosáhnout buď sdílením aplikačního deskriptoru (připojením explicitně přiděleného deskriptoru, který je jak ARD) k jednomu příkazu a APD k jinému), nebo použitím SQLCopyDesc ke zkopírování vazeb mezi ARD a APD obou příkazů. Pokud jsou příkazy na různých připojeních, musí být použit SQLCopyDesc . Kromě toho je nutné volat SQLCopyDesc , aby zkopíroval vazby mezi IRD a IPD obou příkazů. Při kopírování mezi příkazy na stejném spojení musí být SQL_ACTIVE_STATEMENTS informační typ vrácený ovladačem pro volání SQLGetInfo větší než 1, aby tato operace byla úspěšná. (To však neplatí při kopírování přes spojení.)

Příklad kódu

V následujícím příkladu se používají operace deskriptorů ke kopírování polí tabulky PartsSource do tabulky PartsCopy. Obsah tabulky PartsSource je načítán do řádkových bufferů v hstmt0. Tyto hodnoty se používají jako parametry příkazu INSERT na hstmt1 pro vyplnění sloupců tabulky PartsCopy. K tomu jsou pole IRD hstmt0 zkopírována do polí IPD hstmt1 a pole ARD hstmt0 jsou zkopírována do polí APD hstmt1. Použijte SQLSetDescField k nastavení atributu SQL_DESC_PARAMETER_TYPE IPD na SQL_PARAM_INPUT když kopírujete IRD pole z příkazu s výstupními parametry do IPD polí, která potřebují být vstupními parametry.

#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  
Informace o Podívejte se
Získání více deskriptorových polí SQLGetDescRec Function
Nastavení jednoho deskriptorového pole SQLSetDescField Function
Nastavení více deskriptorových polí SQLSetDescRec Function

Viz také

Referenční rozhraní ODBC API
Soubory hlaviček ODBC