Las matrices de parámetros de enlaceBinding Arrays of Parameters

Las aplicaciones que usan matrices de parámetros enlazan las matrices a los parámetros de la instrucción SQL.Applications that use arrays of parameters bind the arrays to the parameters in the SQL statement. Hay dos estilos de enlace:There are two binding styles:

  • Enlazar una matriz a cada parámetro.Bind an array to each parameter. Cada estructura de datos (matriz) contiene todos los datos de un único parámetro.Each data structure (array) contains all the data for a single parameter. Esto se denomina enlace de modo de columna porque enlaza una columna de valores para un parámetro único.This is called column-wise binding because it binds a column of values for a single parameter.

  • Defina una estructura que contenga los datos de parámetro para un conjunto completo de parámetros y enlace una matriz de estas estructuras.Define a structure to hold the parameter data for an entire set of parameters and bind an array of these structures. Cada estructura de datos contiene los datos de una única instrucción SQL.Each data structure contains the data for a single SQL statement. Esto se denomina enlace de modo de fila porque enlaza una fila de parámetros.This is called row-wise binding because it binds a row of parameters.

Como cuando la aplicación enlaza variables únicas a parámetros, llama a SQLBindParameter para enlazar matrices a parámetros.As when the application binds single variables to parameters, it calls SQLBindParameter to bind arrays to parameters. La única diferencia es que las direcciones que se pasan son direcciones de matriz, no direcciones de una sola variable.The only difference is that the addresses passed are array addresses, not single-variable addresses. La aplicación establece el atributo de instrucción SQL_ATTR_PARAM_BIND_TYPE para especificar si utiliza el enlace de modo de columna (el valor predeterminado) o de modo de fila.The application sets the SQL_ATTR_PARAM_BIND_TYPE statement attribute to specify whether it is using column-wise (the default) or row-wise binding. El uso de un enlace de modo de columna o de modo de fila es, en gran medida, una cuestión de preferencia de la aplicación.Whether to use column-wise or row-wise binding is largely a matter of application preference. Dependiendo de cómo el procesador tenga acceso a la memoria, el enlace de modo de fila podría ser más rápido.Depending on how the processor accesses memory, row-wise binding might be faster. Sin embargo, es probable que la diferencia sea insignificante, excepto en el caso de un número muy grande de filas de parámetros.However, the difference is likely to be negligible except for very large numbers of rows of parameters.

El enlaceColumn-Wise Binding

Al utilizar el enlace de modo de columna, una aplicación enlaza una o dos matrices a cada parámetro para el que se van a proporcionar datos.When using column-wise binding, an application binds one or two arrays to each parameter for which data is to be provided. La primera matriz contiene los valores de datos y la segunda contiene búferes de longitud/indicador.The first array holds the data values, and the second array holds length/indicator buffers. Cada matriz contiene tantos elementos como valores para el parámetro.Each array contains as many elements as there are values for the parameter.

El enlace de modo de columna es el valor predeterminado.Column-wise binding is the default. La aplicación también puede cambiar de un enlace de modo de fila a un enlace de modo de columna estableciendo el atributo de instrucción SQL_ATTR_PARAM_BIND_TYPE.The application also can change from row-wise binding to column-wise binding by setting the SQL_ATTR_PARAM_BIND_TYPE statement attribute. En la ilustración siguiente se muestra cómo funciona el enlace de modo de columna.The following illustration shows how column-wise binding works.

Muestra cómo funciona el enlace de-de la columnaShows how column-wise binding works

Por ejemplo, el código siguiente enlaza matrices de 10 elementos a los parámetros de las columnas de códigos de campo, Descripción y precio, y ejecuta una instrucción para insertar 10 filas.For example, the following code binds 10-element arrays to parameters for the PartID, Description, and Price columns, and executes a statement to insert 10 rows. Utiliza el enlace de modo de columna.It uses column-wise 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;  
  
   }  
}  

El enlaceRow-Wise Binding

Cuando se usa el enlace de modo de fila, una aplicación define una estructura para cada conjunto de parámetros.When using row-wise binding, an application defines a structure for each set of parameters. La estructura contiene uno o dos elementos para cada parámetro.The structure contains one or two elements for each parameter. El primer elemento contiene el valor del parámetro y el segundo elemento contiene el búfer de longitud/indicador.The first element holds the parameter value, and the second element holds the length/indicator buffer. A continuación, la aplicación asigna una matriz de estas estructuras, que contiene tantos elementos como valores para cada parámetro.The application then allocates an array of these structures, which contains as many elements as there are values for each parameter.

La aplicación declara el tamaño de la estructura en el controlador con el atributo de instrucción SQL_ATTR_PARAM_BIND_TYPE.The application declares the size of the structure to the driver with the SQL_ATTR_PARAM_BIND_TYPE statement attribute. La aplicación enlaza las direcciones de los parámetros en la primera estructura de la matriz.The application binds the addresses of the parameters in the first structure of the array. Por lo tanto, el controlador puede calcular la dirección de los datos de una fila y columna determinadas comoThus, the driver can calculate the address of the data for a particular row and column as

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

donde las filas se numeran de 1 al tamaño del conjunto de parámetros.where rows are numbered from 1 to the size of the parameter set. El desplazamiento, si está definido, es el valor al que apunta el atributo de instrucción SQL_ATTR_PARAM_BIND_OFFSET_PTR.The offset, if defined, is the value pointed to by the SQL_ATTR_PARAM_BIND_OFFSET_PTR statement attribute. En la ilustración siguiente se muestra cómo funciona el enlace de modo de fila.The following illustration shows how row-wise binding works. Los parámetros se pueden colocar en la estructura en cualquier orden, pero se muestran en orden secuencial para mayor claridad.The parameters can be placed in the structure in any order but are shown in sequential order for clarity.

Muestra cómo funciona el enlace de-de filasShows how row-wise binding works

En el código siguiente se crea una estructura con elementos para los valores que se almacenan en las columnas de código de campo, Descripción y precio.The following code creates a structure with elements for the values to store in the PartID, Description, and Price columns. A continuación, asigna una matriz de 10 elementos de estas estructuras y la enlaza con los parámetros de las columnas de campo de campo, Descripción y precio, utilizando el enlace de modo de fila.It then allocates a 10-element array of these structures and binds it to parameters for the PartID, Description, and Price columns, using row-wise binding. A continuación, ejecuta una instrucción para insertar 10 filas.It then executes a statement to insert 10 rows.

#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;  
  
   }