Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
DbMS definují dlouhá data jako libovolný znak nebo binární data v určité velikosti, například 255 znaků. Tato data mohou být dostatečně malá, aby byla uložena v jedné vyrovnávací paměti, například v popisu obsahující několik tisíc znaků. Může však být příliš dlouhý na uložení do paměti, jako jsou dlouhé textové dokumenty nebo rastrové obrázky. Vzhledem k tomu, že taková data nelze uložit do jedné vyrovnávací paměti, je načtena z ovladače v částech s SQLGetData po načtení ostatních dat v řádku.
Poznámka:
Aplikace může ve skutečnosti načíst libovolný typ dat pomocí SQLGetData, nejen dlouhých dat, ale pouze znak a binární data lze načíst v částech. Pokud jsou však data dostatečně malá, aby se vešla do jedné vyrovnávací paměti, obecně neexistuje důvod použít SQLGetData. Mnohem jednodušší je přiřadit vyrovnávací paměť ke sloupci a umožnit ovladači vrátit data do vyrovnávací paměti.
Pokud chcete načíst dlouhá data ze sloupce, aplikace nejprve volá sqlFetchScroll nebo SQLFetch , aby se přesunula na řádek a načetla data pro vázané sloupce. Aplikace pak volá SQLGetData. SQLGetData má stejné argumenty jako SQLBindCol: popisovač příkazu; číslo sloupce; C datový typ, adresu a bajtovou délku proměnné aplikace; a adresu vyrovnávací paměti pro délku/ukazatel. Obě funkce mají stejné argumenty, protože provádějí v podstatě stejnou úlohu: Obě popisují proměnnou aplikace ovladači a určují, že data pro určitý sloupec by se měla v této proměnné vrátit. Hlavní rozdíly jsou, že SQLGetData je volána po načtení řádku (a někdy se označuje jako pozdní vazba z tohoto důvodu) a že vazba zadaná sqlGetData trvá pouze po dobu trvání volání.
Pokud jde o jeden sloupec, SQLGetData se chová jako SQLFetch: Načte data pro sloupec, převede je na typ proměnné aplikace a vrátí ji v této proměnné. Vrátí také bajtovou délku dat v vyrovnávací paměti délky/ukazatele. Další informace o tom, jak SQLFetch vrací data, naleznete v tématu Načtení řádku dat.
SQLGetData se liší od SQLFetch v jednom důležitém ohledu. Pokud se pro stejný sloupec volá více než jednou po sobě, vrátí každé volání po sobě jdoucí část dat. Každé volání s výjimkou posledního volání vrátí SQL_SUCCESS_WITH_INFO a SQLSTATE 01004 (řetězcová data, zkrácená vpravo); poslední volání vrátí SQL_SUCCESS. Tímto způsobem se SQLGetData používá k načtení dlouhých dat v částech. Pokud se žádná další data nevrátí, vrátí SQLGetData SQL_NO_DATA. Aplikace zodpovídá za sloučení dlouhých dat, což může znamenat zřetězení částí dat. Každá část je ukončena hodnotou null; Aplikace musí při zřetězení částí odebrat znak ukončení s hodnotou null. Načítání dat v částech lze provádět pro záložky s proměnnou délkou i pro další dlouhá data. Hodnota vrácená v vyrovnávací paměti délky/ukazatele se v každém volání snižuje o počet bajtů vrácených v předchozím volání, i když je běžné, že ovladač nemůže zjistit množství dostupných dat a vrátit bajtovou délku SQL_NO_TOTAL. Například:
// Declare a binary buffer to retrieve 5000 bytes of data at a time.
SQLCHAR BinaryPtr[5000];
SQLUINTEGER PartID;
SQLINTEGER PartIDInd, BinaryLenOrInd, NumBytes;
SQLRETURN rc;
SQLHSTMT hstmt;
// Create a result set containing the ID and picture of each part.
SQLExecDirect(hstmt, "SELECT PartID, Picture FROM Pictures", SQL_NTS);
// Bind PartID to the PartID column.
SQLBindCol(hstmt, 1, SQL_C_ULONG, &PartID, 0, &PartIDInd);
// Retrieve and display each row of data.
while ((rc = SQLFetch(hstmt)) != SQL_NO_DATA) {
// Display the part ID and initialize the picture.
DisplayID(PartID, PartIDInd);
InitPicture();
// Retrieve the picture data in parts. Send each part and the number
// of bytes in each part to a function that displays it. The number
// of bytes is always 5000 if there were more than 5000 bytes
// available to return (cbBinaryBuffer > 5000). Code to check if
// rc equals SQL_ERROR or SQL_SUCCESS_WITH_INFO not shown.
while ((rc = SQLGetData(hstmt, 2, SQL_C_BINARY, BinaryPtr, sizeof(BinaryPtr),
&BinaryLenOrInd)) != SQL_NO_DATA) {
NumBytes = (BinaryLenOrInd > 5000) || (BinaryLenOrInd == SQL_NO_TOTAL) ?
5000 : BinaryLenOrInd;
DisplayNextPictPart(BinaryPtr, NumBytes);
}
}
// Close the cursor.
SQLCloseCursor(hstmt);
Použití SQLGetData má několik omezení. Obecně platí, že sloupce, ke kterým se přistupuje pomocí SQLGetData:
Musí být přístupný v pořadí zvýšení počtu sloupců (protože sloupce sady výsledků se čtou ze zdroje dat). Jedná se například o chybu, pokud zavoláte SQLGetData pro sloupec 5 a pak jej zavoláte pro sloupec 4.
Nelze svázat.
Musí mít číslo sloupce vyšší než číslo posledního vázaného sloupce. Pokud je například poslední vázaný sloupec sloupec 3, jedná se o chybu volání SQLGetData pro sloupec 2. Z tohoto důvodu by se aplikace měly ujistit, že na konec vybraného seznamu umístí dlouhé datové sloupce.
Nelze použít, pokud byl volána funkce SQLFetch nebo SQLFetchScroll k načtení více než jednoho řádku. Další informace naleznete v tématu Použití blokových kurzorů.
Některé ovladače tato omezení nevynucují. Interoperabilní aplikace by měly buď předpokládat, že existují, nebo určit, která omezení nejsou vynucena voláním SQLGetInfo s možností SQL_GETDATA_EXTENSIONS.
Pokud aplikace nepotřebuje všechna data ve sloupci znaků nebo binárních dat, může snížit síťový provoz v ovladačích založených na DBMS nastavením atributu příkazu SQL_ATTR_MAX_LENGTH před spuštěním příkazu. Tím se omezí počet bajtů dat, která budou vrácena pro libovolný znak nebo binární sloupec. Předpokládejme například, že sloupec obsahuje dlouhé textové dokumenty. Aplikace, která prochází tabulku obsahující tento sloupec, bude pravděpodobně muset zobrazit pouze první stránku každého dokumentu. I když tento atribut příkazu může být simulován v ovladači, neexistuje žádný důvod k tomu. Konkrétně, pokud aplikace chce zkrátit znaková nebo binární data, měla by svázat malou vyrovnávací paměť se sloupcem pomocí SQLBindCol a nechat ovladač zkrátit data.