Delen via


Binden van arrays van parameters

Toepassingen die matrices van parameters gebruiken, binden de matrices aan de parameters in de SQL-instructie. Er zijn twee bindingsstijlen:

  • Bind een matrix aan elke parameter. Elke gegevensstructuur (matrix) bevat alle gegevens voor één parameter. Dit wordt kolomgebonden binding genoemd omdat hiermee een kolom met waarden voor één parameter wordt gekoppeld.

  • Definieer een structuur voor het opslaan van de parametergegevens voor een hele set parameters en bind een matrix van deze structuren. Elke gegevensstructuur bevat de gegevens voor één SQL-instructie. Dit wordt rijgebonden binding genoemd omdat hiermee een rij met parameters wordt gekoppeld.

Net als wanneer de toepassing enkelvoudige variabelen koppelt aan parameters, roept deze SQLBindParameter aan om matrices te binden aan parameters. Het enige verschil is dat de doorgegeven adressen matrixadressen zijn, niet adressen met één variabele. De toepassing stelt de SQL_ATTR_PARAM_BIND_TYPE-koppelattribuut in om op te geven of het kolomgewijze (de standaard) of rijgewijze binding gebruikt. Of u nu kolomgebonden of rijgebonden binding wilt gebruiken, is grotendeels een kwestie van toepassingsvoorkeur. Afhankelijk van de manier waarop de processor toegang heeft tot het geheugen, kan rijgebonden binding sneller zijn. Het verschil is echter waarschijnlijk te verwaarlozen, met uitzondering van zeer grote aantallen rijen met parameters.

Column-Wise binding

Wanneer u kolomgebonden binding gebruikt, verbindt een toepassing een of twee matrices aan elke parameter waarvoor gegevens moeten worden opgegeven. De eerste matrix bevat de gegevenswaarden en de tweede matrix bevat lengte/indicatorbuffers. Elke matrix bevat zo veel elementen als er waarden voor de parameter zijn.

Kolomgebonden binding is de standaardinstelling. De toepassing kan ook veranderen van rijgebonden binding naar kolombinding door het kenmerk SQL_ATTR_PARAM_BIND_TYPE instructie in te stellen. In de volgende afbeelding ziet u hoe kolomgebonden binding werkt.

Laat zien hoe kolomgebonden binding werkt

Met de volgende code worden bijvoorbeeld matrices van 10 elementen gekoppeld aan parameters voor de kolommen PartID, Description en Price, en wordt een instructie uitgevoerd om 10 rijen in te voegen. Het maakt gebruik van kolomgewijze binding.

#define DESC_LEN 51  
#define ARRAY_SIZE 10  
  
SQLCHAR *      Statement = "INSERT INTO Parts (PartID, Description,  Price) "  
                                                "VALUES (?, ?, ?)";  
SQLUINTEGER    PartIDArray[ARRAY_SIZE];  
SQLCHAR        DescArray[ARRAY_SIZE][DESC_LEN];  
SQLREAL        PriceArray[ARRAY_SIZE];  
SQLINTEGER     PartIDIndArray[ARRAY_SIZE], DescLenOrIndArray[ARRAY_SIZE],  
               PriceIndArray[ARRAY_SIZE];  
SQLUSMALLINT   i, ParamStatusArray[ARRAY_SIZE];  
SQLULEN ParamsProcessed;  
  
memset(DescLenOrIndArray, 0, sizeof(DescLenOrIndArray));  
memset(PartIDIndArray, 0, sizeof(PartIDIndArray));  
memset(PriceIndArray, 0, sizeof(PriceIndArray));  
  
// Set the SQL_ATTR_PARAM_BIND_TYPE statement attribute to use  
// column-wise binding.  
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_BIND_TYPE, SQL_PARAM_BIND_BY_COLUMN, 0);  
  
// Specify the number of elements in each parameter array.  
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMSET_SIZE, ARRAY_SIZE, 0);  
  
// Specify an array in which to return the status of each set of  
// parameters.  
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_STATUS_PTR, ParamStatusArray, 0);  
  
// Specify an SQLUINTEGER value in which to return the number of sets of  
// parameters processed.  
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMS_PROCESSED_PTR, &ParamsProcessed, 0);  
  
// Bind the parameters in column-wise fashion.  
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0,  
                  PartIDArray, 0, PartIDIndArray);  
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, DESC_LEN - 1, 0,  
                  DescArray, DESC_LEN, DescLenOrIndArray);  
SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_REAL, 7, 0,  
                  PriceArray, 0, PriceIndArray);  
  
// Set part ID, description, and price.  
for (i = 0; i < ARRAY_SIZE; i++) {  
   GetNewValues(&PartIDArray[i], DescArray[i], &PriceArray[i]);  
   PartIDIndArray[i] = 0;  
   DescLenOrIndArray[i] = SQL_NTS;  
   PriceIndArray[i] = 0;  
}  
  
// Execute the statement.  
SQLExecDirect(hstmt, Statement, SQL_NTS);  
  
// Check to see which sets of parameters were processed successfully.  
for (i = 0; i < ParamsProcessed; i++) {  
   printf("Parameter Set  Status\n");  
   printf("-------------  -------------\n");  
   switch (ParamStatusArray[i]) {  
      case SQL_PARAM_SUCCESS:  
      case SQL_PARAM_SUCCESS_WITH_INFO:  
         printf("%13d  Success\n", i);  
         break;  
  
      case SQL_PARAM_ERROR:  
         printf("%13d  Error\n", i);  
         break;  
  
      case SQL_PARAM_UNUSED:  
         printf("%13d  Not processed\n", i);  
         break;  
  
      case SQL_PARAM_DIAG_UNAVAILABLE:  
         printf("%13d  Unknown\n", i);  
         break;  
  
   }  
}  

Row-Wise bindingen

Wanneer u rijgebonden binding gebruikt, definieert een toepassing een structuur voor elke set parameters. De structuur bevat een of twee elementen voor elke parameter. Het eerste element bevat de parameterwaarde en het tweede element bevat de lengte/indicatorbuffer. De toepassing wijst vervolgens een matrix van deze structuren toe, die zo veel elementen bevat als er waarden voor elke parameter zijn.

De toepassing geeft de grootte van de structuur aan het stuurprogramma op met het statement-attribuut SQL_ATTR_PARAM_BIND_TYPE. De toepassing verbindt de adressen van de parameters in de eerste structuur van de matrix. Het stuurprogramma kan dus het adres van de gegevens voor een bepaalde rij en kolom berekenen als

Address = Bound Address + ((Row Number - 1) * Structure Size) + Offset  

waarbij rijen worden genummerd van 1 tot de grootte van de parameterset. De offset, indien gedefinieerd, is de waarde waarnaar wordt verwezen door het statementkenmerk SQL_ATTR_PARAM_BIND_OFFSET_PTR. In de volgende afbeelding ziet u hoe rijgebonden binding werkt. De parameters kunnen in elke volgorde in de structuur worden geplaatst, maar worden sequentieel weergegeven voor duidelijkheid.

Laat zien hoe rijgebonden binding werkt

Met de volgende code wordt een structuur gemaakt met elementen voor de waarden die moeten worden opgeslagen in de kolommen PartID, Description en Price. Vervolgens wordt een matrix van 10 elementen van deze structuren toegewezen en gekoppeld aan parameters voor de kolommen PartID, Description en Price, met behulp van rijbinding. Vervolgens wordt een instructie uitgevoerd om 10 rijen in te voegen.

#define DESC_LEN 51  
#define ARRAY_SIZE 10  
  
typedef tagPartStruct {  
   SQLREAL       Price;  
   SQLUINTEGER   PartID;  
   SQLCHAR       Desc[DESC_LEN];  
   SQLINTEGER    PriceInd;  
   SQLINTEGER    PartIDInd;  
   SQLINTEGER    DescLenOrInd;  
} PartStruct;  
  
PartStruct PartArray[ARRAY_SIZE];  
SQLCHAR *      Statement = "INSERT INTO Parts (PartID, Description,  
                Price) "  
               "VALUES (?, ?, ?)";  
SQLUSMALLINT   i, ParamStatusArray[ARRAY_SIZE];  
SQLULEN ParamsProcessed;  
  
// Set the SQL_ATTR_PARAM_BIND_TYPE statement attribute to use  
// column-wise binding.  
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_BIND_TYPE, sizeof(PartStruct), 0);  
  
// Specify the number of elements in each parameter array.  
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMSET_SIZE, ARRAY_SIZE, 0);  
  
// Specify an array in which to return the status of each set of  
// parameters.  
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_STATUS_PTR, ParamStatusArray, 0);  
  
// Specify an SQLUINTEGER value in which to return the number of sets of  
// parameters processed.  
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMS_PROCESSED_PTR, &ParamsProcessed, 0);  
  
// Bind the parameters in row-wise fashion.  
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0,  
                  &PartArray[0].PartID, 0, &PartArray[0].PartIDInd);  
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, DESC_LEN - 1, 0,  
                  PartArray[0].Desc, DESC_LEN, &PartArray[0].DescLenOrInd);  
SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_REAL, 7, 0,  
                  &PartArray[0].Price, 0, &PartArray[0].PriceInd);  
  
// Set part ID, description, and price.  
for (i = 0; i < ARRAY_SIZE; i++) {  
   GetNewValues(&PartArray[i].PartID, PartArray[i].Desc, &PartArray[i].Price);  
   PartArray[0].PartIDInd = 0;  
   PartArray[0].DescLenOrInd = SQL_NTS;  
   PartArray[0].PriceInd = 0;  
}  
  
// Execute the statement.  
SQLExecDirect(hstmt, Statement, SQL_NTS);  
  
// Check to see which sets of parameters were processed successfully.  
for (i = 0; i < ParamsProcessed; i++) {  
   printf("Parameter Set  Status\n");  
   printf("-------------  -------------\n");  
   switch (ParamStatusArray[i]) {  
      case SQL_PARAM_SUCCESS:  
      case SQL_PARAM_SUCCESS_WITH_INFO:  
         printf("%13d  Success\n", i);  
         break;  
  
      case SQL_PARAM_ERROR:  
         printf("%13d  Error\n", i);  
         break;  
  
      case SQL_PARAM_UNUSED:  
         printf("%13d  Not processed\n", i);  
         break;  
  
      case SQL_PARAM_DIAG_UNAVAILABLE:  
         printf("%13d  Unknown\n", i);  
         break;  
  
   }