Aracılığıyla paylaş


SQLBindCol kullanma

Uygulama SQLBindCol çağırarak sütunları bağlar. Bu işlev bir kerede bir sütun bağlar. Bununla birlikte, uygulama aşağıdakileri belirtir:

  • Sütun numarası. 0. sütun yer işareti sütunudur; bu sütun bazı sonuç kümelerine dahil değildir. Diğer tüm sütunlar 1 sayısıyla başlayarak numaralandırılır. Sonuç kümesinde sütun sayısından daha yüksek numaralı bir sütunu bağlamak bir hatadır; sonuç kümesi oluşturulana kadar bu hata algılanamaz, bu nedenle SQLBindCol tarafından değil SQLFetch tarafından döndürülür.

  • Değişkenin sütuna bağlandığı C veri tipi, adresi ve bayt uzunluğu. Sütunun SQL veri türünün dönüştürülemeyeceği bir C veri türü belirtmek bir hatadır; bu hata sonuç kümesi oluşturulana kadar algılanmayabilir, bu nedenle SQLBindCol tarafından değil SQLFetch tarafından döndürülür. Desteklenen dönüştürmelerin listesi için bkz. Ek D: Veri Türleri'nde Verileri SQL'den C Veri Türlerine Dönüştürme . Bayt uzunluğu hakkında bilgi için bkz. Veri Arabellek Uzunluğu.

  • Uzunluk/gösterge arabelleğinin adresi. Uzunluk/gösterge arabelleği isteğe bağlıdır. İkili veya karakter verilerinin bayt uzunluğunu döndürmek veya veriler NULL ise SQL_NULL_DATA döndürmek için kullanılır. Daha fazla bilgi için bkz. Uzunluk/Gösterge Değerlerini Kullanma.

SQLBindCol çağrıldığında, sürücü bu bilgileri deyimiyle ilişkilendirir. Her veri satırı getirildiğinde, ilgili uygulama değişkenlerine her sütunun verilerini yerleştirmek için bilgileri kullanır.

Örneğin, aşağıdaki kod değişkenleri SalesPerson ve CustID sütunlarına bağlar. Sütunların verileri SalesPerson ve CustID içinde döndürülür. SalesPerson bir karakter arabelleği olduğundan uygulama bayt uzunluğunu (11) belirtir, böylece sürücü verileri kesip kesmeyeceğini belirleyebilir. Döndürülen başlığın bayt uzunluğu veya NULL olup olmadığı SalesPersonLenOrInd içinde döndürülür.

CustID bir tamsayı değişkeni olduğundan ve uzunluğu sabit olduğundan bayt uzunluğunu belirtmeye gerek yoktur; sürücü bunun sizeof(SQLUINTEGER) olduğunu varsayar. Döndürülen müşteri kimliği verilerinin bayt uzunluğu veya NULL olup olmadığı CustIDInd içinde döndürülür. Bayt uzunluğu her zaman sizeof(SQLUINTEGER) olduğundan uygulamanın yalnızca maaşın NULL olup olmadığıyla ilgilendiğini unutmayın.

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

Aşağıdaki kod, kullanıcı tarafından girilen bir SELECT deyimini yürütür ve sonuç kümesindeki her veri satırını yazdırır. Uygulama SELECT deyimi tarafından oluşturulan sonuç kümesinin şeklini tahmin edemeyeceğinden, önceki örnekte olduğu gibi sabit kodlanmış değişkenleri sonuç kümesine bağlayamaz. Bunun yerine, uygulama verileri tutan bir arabellek ve bu satırdaki her sütun için bir uzunluk/gösterge arabelleği ayırır. Her sütun için, sütunun belleğinin başına uzaklığı hesaplar ve bu uzaklığı, sütun için veri ve uzunluk/gösterge arabelleklerinin hizalama sınırlarında başlaması için ayarlar. Ardından, ofsetten başlayarak belleği sütuna bağlar. Sürücünün bakış açısından, bu belleğin adresi, önceki örnekteki bir değişkenin adresinden ayırt edilemez. Hizalama hakkında daha fazla bilgi için bkz . Hizalama.

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