Megosztás:


Hosszú adatok lekérése

A DBMS-ek a hosszú adatokat bármely karakterként vagy bináris adatként definiálják egy adott méreten, például 255 karakteren. Ezek az adatok elég kicsik lehetnek ahhoz, hogy egyetlen pufferben legyenek tárolva, például több ezer karakterből álló részleírásban. Előfordulhat azonban, hogy túl hosszú a memóriában tárolni, például hosszú szöveges dokumentumokat vagy bitképeket. Mivel ezek az adatok nem tárolhatók egyetlen pufferben, a rendszer az SQLGetData-tal rendelkező részekben kéri le az illesztőprogramból a sor többi adatának beolvasása után.

Megjegyzés:

Az alkalmazások valójában bármilyen típusú adatot lekérhetnek az SQLGetData használatával, nem csak a hosszú adatokat, bár csak karakter- és bináris adatok kérhetők le részekben. Ha azonban az adatok elég kicsik ahhoz, hogy egyetlen pufferben elférjenek, általában nincs ok az SQLGetData használatára. Sokkal egyszerűbb egy puffert az oszlophoz kötni, és lehetővé tenni, hogy az illesztőprogram visszaadja a pufferben lévő adatokat.

Ha hosszú adatokat szeretne lekérni egy oszlopból, az alkalmazás először meghívja az SQLFetchScrollt vagy az SQLFetchet , hogy lépjen egy sorba, és lekérje a kötött oszlopok adatait. Az alkalmazás ezután meghívja az SQLGetData-t. Az SQLGetData argumentumai ugyanazok, mint az SQLBindCol: egy utasításkezelő; oszlopszám; egy alkalmazásváltozó C adattípusa, címe és bájthossza; és egy hossz-/mutatópuffer címét. Mindkét függvény ugyanazokkal az argumentumokkal rendelkezik, mivel lényegében ugyanazt a feladatot hajtják végre: Mindkettő egy alkalmazásváltozót ír le az illesztőprogramnak, és megadják, hogy egy adott oszlop adatait vissza kell adni ebben a változóban. A fő különbségek az, hogy az SQLGetData meghívása egy sor lekérése után történik (ezért néha késői kötésnek is nevezik), és hogy az SQLGetData által megadott kötés csak a hívás időtartamára tart.

Egyetlen oszlop esetében az SQLGetData az SQLFetchhez hasonlóan viselkedik: Lekéri az oszlop adatait, átalakítja azokat az alkalmazásváltozó típusára, és visszaadja azokat ebben a változóban. Emellett visszaadja az adatok bájthosszát a hossz/mutató pufferében. Az SQLFetch által visszaadott adatokról további információt az Adatsor beolvasása című témakörben talál.

Az SQLGetData egy fontos szempontból különbözik az SQLFetch-től. Ha egymás után többször meghívja ugyanazt az oszlopot, minden hívás az adatok egy újabb egymást követő részét adja vissza. Az utolsó hívás kivételével minden hívás SQL_SUCCESS_WITH_INFO-t és SQLSTATE 01004-et (Sztringadatok, jobbról csonkolt) ad vissza; az utolsó hívás SQL_SUCCESS-t ad. Az SQLGetData így kéri le a hosszú adatokat részekben. Ha nincs több visszaadandó adat, az SQLGetData SQL_NO_DATA ad vissza. Az alkalmazás feladata a hosszú adatok összefűzése, ami az adatok részeinek összefűzését jelentheti. Minden rész nullával végződik; az alkalmazásnak el kell távolítania a null karaktert, ha összefűzi a részeket. A részekben lévő adatok beolvasása elvégezhető változó hosszúságú könyvjelzőkhöz és más hosszú adatokhoz is. A hossz/mutató pufferben visszaadott érték az egyes hívásokban az előző hívásban visszaadott bájtok számával csökken, bár gyakori, hogy az illesztőprogram nem tudja felderíteni a rendelkezésre álló adatok mennyiségét, és SQL_NO_TOTAL bájthosszt ad vissza. Például:

// 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);  

Az SQLGetData használatára számos korlátozás vonatkozik. Az SQLGetData szolgáltatással elérhető oszlopok általában:

  • Az oszlopokhoz növekvő sorrendben kell hozzáférni (mivel az eredményhalmaz oszlopai így kerülnek beolvasásra az adatforrásból). Hiba például az SQLGetData meghívása az 5. oszlophoz, majd a 4. oszlop meghívása.

  • Nem köthető.

  • Az utolsó kötött oszlopnál nagyobb oszlopszámmal kell rendelkeznie. Ha például az utolsó kötött oszlop a 3. oszlop, akkor hiba az SQLGetData meghívása a 2. oszlophoz. Ezért az alkalmazásoknak meg kell győződnie arról, hogy hosszú adatoszlopokat helyeznek el a kiválasztási lista végén.

  • Nem használható, ha az SQLFetch vagy az SQLFetchScroll egynél több sor lekérésére lett meghívva. További információt a Blokkkurzorok használata című témakörben talál.

Egyes illesztőprogramok nem érvényesítik ezeket a korlátozásokat. Az interoperábilis alkalmazásoknak feltételezniük kell, hogy léteznek, vagy az SQLGetInfo SQL_GETDATA_EXTENSIONS lehetőséggel való meghívásával állapítják meg, hogy mely korlátozások nincsenek kényszerítve.

Ha az alkalmazásnak nincs szüksége az összes adatra egy karakter- vagy bináris adatoszlopban, csökkentheti a hálózati forgalmat a DBMS-alapú illesztőprogramokban a SQL_ATTR_MAX_LENGTH utasítás attribútum beállításával az utasítás végrehajtása előtt. Ez korlátozza a bármely karakterhez vagy bináris oszlophoz visszaadott adatok bájtjainak számát. Tegyük fel például, hogy egy oszlop hosszú szöveges dokumentumokat tartalmaz. Előfordulhat, hogy az oszlopot tartalmazó táblát böngésző alkalmazásnak csak az egyes dokumentumok első oldalát kell megjelenítenie. Bár ez az utasításattribútum szimulálható az illesztőprogramban, erre nincs ok. Ha egy alkalmazás karakter- vagy bináris adatokat szeretne csonkítani, akkor az SQLBindCol segítségével egy kis puffert kell az oszlophoz kötnie, és lehetővé kell tenni, hogy az illesztőprogram csonkolassa az adatokat.