Resultaatgegevens ophalen

van toepassing op:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)

Een ODBC-applicatie heeft drie opties om resultaatgegevens op te halen.

De eerste optie is gebaseerd op SQLBindCol. Voordat de resultaatset wordt opgehaald, gebruikt de applicatie SQLBindCol om elke kolom in de resultaatset te binden aan een programmavariabele. Nadat de kolommen zijn gebonden, zet de driver de gegevens van de huidige rij over in de variabelen die aan de kolommen van de resultaatset zijn gekoppeld, telkens wanneer de applicatie SQLFetch of SQLFetchScroll aanroept. De driver verwerkt dataconversies als de kolom van de resultaatset en de programmavariabele verschillende datatypes hebben. Als de applicatie SQL_ATTR_ROW_ARRAY_SIZE set groter dan 1 heeft, kan het resultaatkolommen binden aan arrays van variabelen, die allemaal worden gevuld bij elke aanroep naar SQLFetchScroll.

De tweede optie is gebaseerd op SQLGetData. De applicatie gebruikt SQLBindCol niet om kolommen van de resultaatset aan programmavariabelen te binden. Na elke aanroep van SQLFetch roept de applicatie SQLGetData één keer aan voor elke kolom in de resultaatset. SQLGetData instrueert de driver om gegevens over te dragen van een specifieke resultaatverzamelkolom naar een specifieke programmavariabele en specificeert de datatypen van de kolom en variabele. Dit stelt de driver in staat om data om te zetten als de resultaatkolom en de programmavariabele verschillende datatypes hebben. Kolommen tekst, ntext en afbeelding zijn meestal te groot om in een programmavariabele te passen, maar kunnen nog steeds worden opgehaald met SQLGetData. Als de tekst-, ntext- of afbeeldingsgegevens in de resultaatkolom groter zijn dan de programmavariabele, geeft SQLGetData SQL_SUCCESS_WITH_INFO en SQLSTATE 01004 (stringgegevens, rechts afgekapt) terug. Opeenvolgende aanroepen naar SQLGetData geven opeenvolgende stukken van de tekst- of afbeeldingsgegevens terug. Wanneer het einde van de data is bereikt, keert SQLGetData terug SQL_SUCCESS. Elke fetch geeft een set rijen, of rijset, terug als SQL_ATTR_ROW_ARRAY_SIZE groter is dan 1. Voordat je SQLGetData gebruikt, moet je eerst SQLSetPos gebruiken om een specifieke rij binnen de rijset als de huidige rij te specificeren.

De derde optie is het gebruik van een mix van SQLBindCol en SQLGetData. Een applicatie zou bijvoorbeeld de eerste tien kolommen van een resultaatset kunnen binden en vervolgens bij elke fetch SQLGetData drie keer kunnen aanroepen om de data uit drie niet-gebonden kolommen op te halen. Dit wordt doorgaans gebruikt wanneer een resultaatset één of meer tekst- of afbeeldingskolommen bevat.

Afhankelijk van de cursoropties die voor de resultaatset zijn ingesteld, kan een applicatie ook de scrollopties van SQLFetchScroll gebruiken om door de resultaatset te scrollen.

Overmatig gebruik van SQLBindCol om een kolom van een resultaatset aan een programmavariabele te binden is duur omdat SQLBindCol ervoor zorgt dat een ODBC-driver geheugen toewijst. Wanneer je een resultaatkolom bindt aan een variabele, blijft die binding van kracht totdat je ofwel SQLFreeHandle aanroept om de statementhandle vrij te maken of SQLFreeStmt aanroept met fOption op SQL_UNBIND. De bindings worden niet automatisch ongedaan gemaakt wanneer de instructie voltooid is.

Deze logica stelt je in staat om effectief dezelfde SELECT-instructie meerdere keren uit te voeren met verschillende parameters. Omdat de resultaatset dezelfde structuur behoudt, kun je de resultaatset één keer binden, alle SELECT-statements verwerken en daarna SQLFreeStmt aanroepen met fOption ingesteld op SQL_UNBIND na de laatste uitvoering. Je moet SQLBindCol niet aanroepen om de kolommen in een resultaatset te binden zonder eerst SQLFreeStmt aan te roepen met fOption ingesteld op SQL_UNBIND om eerdere bindings vrij te maken.

Bij het gebruik van SQLBindCol kun je zowel rij- als kolombinding doen. Rij-gebonden binding is iets sneller dan kolom-gebonden binding.

Je kunt SQLGetData gebruiken om data kolom-voor-kolom op te halen in plaats van resultaatsetkolommen te binden met SQLBindCol. Als een resultaatset slechts een paar rijen bevat, is het gebruik van SQLGetData in plaats van SQLBindCol sneller; anders levert SQLBindCol de beste prestaties. Als je de data niet altijd in dezelfde set variabelen plaatst, moet je SQLGetData gebruiken in plaats van constant opnieuw te binden. Je kunt SQLGetData alleen gebruiken op kolommen die in de selectielijst staan nadat alle kolommen met SQLBindCol zijn gebonden. De kolom moet ook verschijnen na alle kolommen waarop je SQLGetData al hebt gebruikt.

De ODBC-functies die zich bezighouden met het verplaatsen van data in of uit programmavariabelen, zoals SQLGetData, SQLBindCol en SQLBindParameter, ondersteunen impliciete datatypeconversie. Als een applicatie bijvoorbeeld een gehele kolom bindt aan een tekenreeks-programmavariabele, zet de driver de gegevens automatisch om van geheel getal naar teken voordat deze in de programmavariabele wordt geplaatst.

Dataconversie in applicaties moet worden geminimaliseerd. Tenzij dataconversie vereist is voor de verwerking door de applicatie, zouden applicaties kolommen en parameters moeten binden aan programmavariabelen van hetzelfde datatype. Als de data echter van het ene type naar het andere moet worden omgezet, is het efficiënter om de driver de conversie te laten uitvoeren dan in de applicatie. De SQL Server Native Client ODBC-driver draagt normaal gesproken gewoon data direct van de netwerkbuffers over naar de variabelen van de applicatie. Het verzoeken van de driver om dataconversie uit te voeren, dwingt de driver om de data te bufferen en CPU-cycli te gebruiken om de data te converteren.

Programmavariabelen moeten groot genoeg zijn om gegevens die vanuit een kolom worden overgezet vast te houden, behalve voor tekst-, ntext- en afbeeldingsgegevens . Als een applicatie probeert resultaatsetgegevens op te halen en deze in een te kleine variabele te plaatsen om deze vast te houden, genereert de driver een waarschuwing. Dit dwingt de driver om geheugen toe te wijzen voor het bericht, en zowel de driver als de applicatie moeten CPU-cycli besteden aan het verwerken van het bericht en het afhandelen van fouten. De applicatie moet ofwel een variabele toewijzen die groot genoeg is om de opgehaalde data te bevatten, of de SUBSTRING-functie in de select-lijst gebruiken om de grootte van de kolom in de resultaatset te verkleinen.

Bij het gebruik van SQL_C_DEFAULT moet voorzichtig worden betracht om het type van de C-variabele te specificeren. SQL_C_DEFAULT specificeert dat het type van de C-variabele overeenkomt met het SQL-datatype van de kolom of parameter. Als SQL_C_DEFAULT is gespecificeerd voor een ntext-, nchar- of nvarchar-kolom , wordt Unicode-gegevens teruggegeven aan de applicatie. Dit kan verschillende problemen veroorzaken als de applicatie niet is gecodeerd om Unicode-gegevens te verwerken. Dezelfde soorten problemen kunnen optreden met het unieke identifier (SQL_GUID) datatype.

tekst-, ntext- en afbeeldingsgegevens zijn doorgaans te groot om in één enkele programmavariabele te passen, en worden meestal verwerkt met SQLGetData in plaats van SQLBindCol. Bij gebruik van servercursors is de SQL Server Native Client ODBC-driver geoptimaliseerd om de gegevens voor ongebonden tekst,ntext- of afbeeldingskolommen niet te verzenden op het moment dat de rij wordt opgehaald. De tekst-, ntext- of afbeeldingsgegevens worden pas daadwerkelijk van de server opgehaald als de applicatie SQLGetData voor de kolom uitgeeft.

Deze optimalisatie kan worden toegepast op applicaties zodat er geen tekst-, ntext- of afbeeldingsgegevens worden weergegeven terwijl een gebruiker op en neer scrolt. Nadat de gebruiker een rij heeft geselecteerd, kan de applicatie SQLGetData aanroepen om de tekst-, ntext- of afbeeldingsgegevens op te halen. Dit bespaart het verzenden van tekst-, ntext- of afbeeldingsgegevens voor alle rijen die de gebruiker niet selecteert en kan de verzending van zeer grote hoeveelheden data opslaan.