Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
De toepassing verbindt kolommen door SQLBindCol aan te roepen. Met deze functie wordt één kolom tegelijk gekoppeld. Hiermee geeft de toepassing het volgende op:
Het kolomnummer. Kolom 0 is de bladwijzerkolom; deze kolom is niet opgenomen in sommige resultatensets. Alle andere kolommen worden genummerd vanaf het getal 1. Het is een fout om een hogere genummerde kolom te binden dan er kolommen in de resultatenset staan; deze fout kan niet worden gedetecteerd totdat de resultatenset is gemaakt, dus wordt deze geretourneerd door SQLFetch, niet SQLBindCol.
Het gegevenstype C, het adres en de bytelengte van de variabele die aan de kolom is gebonden. Het is een fout om een C-gegevenstype op te geven waarnaar het SQL-gegevenstype van de kolom niet kan worden geconverteerd; deze fout kan niet worden gedetecteerd totdat de resultatenset is gemaakt, dus wordt deze geretourneerd door SQLFetch, niet SQLBindCol. Zie Gegevens converteren van SQL naar C-gegevenstypen in bijlage D: gegevenstypen voor een lijst met ondersteunde conversies. Zie De lengte van de gegevensbuffer voor informatie over de bytelengte.
Het adres van een lengte/indicatorbuffer. De lengte/indicatorbuffer is optioneel. Het wordt gebruikt om de bytelengte van binaire of tekengegevens te retourneren of SQL_NULL_DATA te retourneren indien de gegevens NULL zijn. Zie Lengte-/indicatorwaarden gebruiken voor meer informatie.
Wanneer SQLBindCol wordt aangeroepen, koppelt het stuurprogramma deze informatie aan de instructie. Wanneer elke rij met gegevens wordt opgehaald, wordt de informatie gebruikt om de gegevens voor elke kolom in de afhankelijke toepassingsvariabelen te plaatsen.
Met de volgende code worden variabelen bijvoorbeeld gekoppeld aan de kolommen SalesPerson en CustID. Gegevens voor de kolommen worden geretourneerd in SalesPerson en CustID. Omdat SalesPerson een tekenbuffer is, geeft de toepassing de bytelengte (11) op, zodat het stuurprogramma kan bepalen of de gegevens moeten worden afgekapt. De bytelengte van de geretourneerde titel, of of het NULL is, wordt geretourneerd in SalesPersonLenOrInd.
Omdat CustID een gehele getalvariabele is en vaste lengte heeft, hoeft u de bytelengte niet op te geven; in het stuurprogramma wordt ervan uitgegaan dat het sizeof(SQLUINTEGER) is. De byte-lengte van de geretourneerde klant-ID-gegevens, of of deze NULL is, wordt geretourneerd in CustIDInd. Houd er rekening mee dat de toepassing alleen geïnteresseerd is in het feit of het salaris NULL is, omdat de bytelengte altijd sizeof (SQLUINTEGER) is.
SQLCHAR SalesPerson[11];
SQLUINTEGER CustID;
SQLINTEGER SalesPersonLenOrInd, CustIDInd;
SQLRETURN rc;
SQLHSTMT hstmt;
// Bind SalesPerson to the SalesPerson column and CustID to the
// CustID column.
SQLBindCol(hstmt, 1, SQL_C_CHAR, SalesPerson, sizeof(SalesPerson),
&SalesPersonLenOrInd);
SQLBindCol(hstmt, 2, SQL_C_ULONG, &CustID, 0, &CustIDInd);
// Execute a statement to get the sales person/customer of all orders.
SQLExecDirect(hstmt, "SELECT SalesPerson, CustID FROM Orders ORDER BY SalesPerson",
SQL_NTS);
// Fetch and print the data. Print "NULL" if the data is NULL. Code to
// check if rc equals SQL_ERROR or SQL_SUCCESS_WITH_INFO not shown.
while ((rc = SQLFetch(hstmt)) != SQL_NO_DATA) {
if (SalesPersonLenOrInd == SQL_NULL_DATA)
printf("NULL ");
else
printf("%10s ", SalesPerson);
if (CustIDInd == SQL_NULL_DATA)
printf("NULL\n");
else
printf("%d\n", CustID);
}
// Close the cursor.
SQLCloseCursor(hstmt);
Met de volgende code wordt een SELECT-instructie uitgevoerd die door de gebruiker is ingevoerd en wordt elke rij met gegevens in de resultatenset afgedrukt. Omdat de toepassing de vorm van de resultatenset die is gemaakt met de SELECT-instructie niet kan voorspellen, kan de toepassing geen in code vastgelegde variabelen binden aan de resultatenset zoals in het voorgaande voorbeeld. In plaats daarvan wijst de toepassing een buffer toe die de gegevens en een lengte/indicatorbuffer bevat voor elke kolom in die rij. Voor elke kolom wordt de offset naar het begin van het kolomgeheugen berekend en wordt deze offset aangepast, zodat de gegevens- en lengte/indicatorbuffers van de kolom op uitlijningsgrenzen beginnen. Vervolgens wordt het geheugen dat begint bij de offset, gekoppeld aan de kolom. Vanuit het oogpunt van het stuurprogramma is het adres van dit geheugen niet te onderscheiden van het adres van een variabele die in het voorgaande voorbeeld is gebonden. Voor meer informatie over uitlijning, zie Uitlijning.
// This application allocates a buffer at run time. For each column, this
// buffer contains memory for the column's data and length/indicator.
// For example:
// column 1 column 2 column 3 column 4
// <------------><---------------><-----><------------>
// db1 li1 db2 li2 db3 li3 db4 li4
// | | | | | | | |
// _____V_____V________V_______V___V___V______V_____V_
// |__________|__|_____________|__|___|__|__________|__|
//
// dbn = data buffer for column n
// lin = length/indicator buffer for column n
// Define a macro to increase the size of a buffer so that it is a
// multiple of the alignment size. Thus, if a buffer starts on an
// alignment boundary, it will end just before the next alignment
// boundary. In this example, an alignment size of 4 is used because
// this is the size of the largest data type used in the application's
// buffer--the size of an SDWORD and of the largest default C data type
// are both 4. If a larger data type (such as _int64) was used, it would
// be necessary to align for that size.
#define ALIGNSIZE 4
#define ALIGNBUF(Length) Length % ALIGNSIZE ? \
Length + ALIGNSIZE - (Length % ALIGNSIZE) : Length
SQLCHAR SelectStmt[100];
SQLSMALLINT NumCols, *CTypeArray, i;
SQLINTEGER * ColLenArray, *OffsetArray, SQLType, *DataPtr;
SQLRETURN rc;
SQLHSTMT hstmt;
// Get a SELECT statement from the user and execute it.
GetSelectStmt(SelectStmt, 100);
SQLExecDirect(hstmt, SelectStmt, SQL_NTS);
// Determine the number of result set columns. Allocate arrays to hold
// the C type, byte length, and buffer offset to the data.
SQLNumResultCols(hstmt, &NumCols);
CTypeArray = (SQLSMALLINT *) malloc(NumCols * sizeof(SQLSMALLINT));
ColLenArray = (SQLINTEGER *) malloc(NumCols * sizeof(SQLINTEGER));
OffsetArray = (SQLINTEGER *) malloc(NumCols * sizeof(SQLINTEGER));
OffsetArray[0] = 0;
for (i = 0; i < NumCols; i++) {
// Determine the column's SQL type. GetDefaultCType contains a switch
// statement that returns the default C type for each SQL type.
SQLColAttribute(hstmt, ((SQLUSMALLINT) i) + 1, SQL_DESC_TYPE, NULL, 0, NULL, (SQLPOINTER) &SQLType);
CTypeArray[i] = GetDefaultCType(SQLType);
// Determine the column's byte length. Calculate the offset in the
// buffer to the data as the offset to the previous column, plus the
// byte length of the previous column, plus the byte length of the
// previous column's length/indicator buffer. Note that the byte
// length of the column and the length/indicator buffer are increased
// so that, assuming they start on an alignment boundary, they will
// end on the byte before the next alignment boundary. Although this
// might leave some holes in the buffer, it is a relatively
// inexpensive way to guarantee alignment.
SQLColAttribute(hstmt, ((SQLUSMALLINT) i)+1, SQL_DESC_OCTET_LENGTH, NULL, 0, NULL, &ColLenArray[i]);
ColLenArray[i] = ALIGNBUF(ColLenArray[i]);
if (i)
OffsetArray[i] = OffsetArray[i-1]+ColLenArray[i-1]+ALIGNBUF(sizeof(SQLINTEGER));
}
// Allocate the data buffer. The size of the buffer is equal to the
// offset to the data buffer for the final column, plus the byte length
// of the data buffer and length/indicator buffer for the last column.
void *DataPtr = malloc(OffsetArray[NumCols - 1] +
ColLenArray[NumCols - 1] + ALIGNBUF(sizeof(SQLINTEGER)));
// For each column, bind the address in the buffer at the start of the
// memory allocated for that column's data and the address at the start
// of the memory allocated for that column's length/indicator buffer.
for (i = 0; i < NumCols; i++)
SQLBindCol(hstmt,
((SQLUSMALLINT) i) + 1,
CTypeArray[i],
(SQLPOINTER)((SQLCHAR *)DataPtr + OffsetArray[i]),
ColLenArray[i],
(SQLINTEGER *)((SQLCHAR *)DataPtr + OffsetArray[i] + ColLenArray[i]));
// Retrieve and print each row. PrintData accepts a pointer to the data,
// its C type, and its byte length/indicator. It contains a switch
// statement that casts and prints the data according to its type. Code
// to check if rc equals SQL_ERROR or SQL_SUCCESS_WITH_INFO not shown.
while ((rc = SQLFetch(hstmt)) != SQL_NO_DATA) {
for (i = 0; i < NumCols; i++) {
PrintData((SQLCHAR *)DataPtr[OffsetArray[i]], CTypeArray[i],
(SQLINTEGER *)((SQLCHAR *)DataPtr[OffsetArray[i] + ColLenArray[i]]));
}
}
// Close the cursor.
SQLCloseCursor(hstmt);