Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Aplicações que utilizam arrays de parâmetros associam os arrays aos parâmetros da instrução SQL. Existem dois estilos de encadernação:
Liga um array a cada parâmetro. Cada estrutura de dados (array) contém todos os dados de um único parâmetro. Isto é chamado ligação por coluna porque liga uma coluna de valores para um único parâmetro.
Defina uma estrutura para armazenar os dados dos parâmetros de um conjunto inteiro de parâmetros e associe um array dessas estruturas. Cada estrutura de dados contém os dados para uma única instrução SQL. Isto chama-se ligação em linha porque liga uma linha de parâmetros.
Tal como quando a aplicação liga variáveis individuais a parâmetros, chama SQLBindParameter para ligar arrays a parâmetros. A única diferença é que os endereços passados são endereços de array, não endereços de variável única. A aplicação define o atributo da instrução SQL_ATTR_PARAM_BIND_TYPE para especificar se está a usar a ligação por coluna (o padrão) ou por linha. Se se deve usar a ligação por colunas ou por linhas é, em grande parte, uma questão de preferência de aplicação. Dependendo de como o processador acede à memória, a ligação linha a linha pode ser mais rápida. No entanto, a diferença é provavelmente negligenciável, exceto por um número muito grande de linhas de parâmetros.
Column-Wise Vinculação
Ao usar ligação por colunas, uma aplicação associa um ou dois arrays a cada parâmetro para o qual os dados devem ser fornecidos. O primeiro array contém os valores de dados, e o segundo array contém buffers de comprimento/indicadores. Cada array contém tantos elementos quantos valores houver para o parâmetro.
A encadernação por colunas é o padrão. A aplicação também pode mudar de ligação por linhas para ligação por colunas, definindo o atributo de instrução SQL_ATTR_PARAM_BIND_TYPE. A ilustração seguinte mostra como funciona a encadernação por colunas.
Por exemplo, o código seguinte liga arrays de 10 elementos aos parâmetros das colunas PartID, Description e Price, e executa uma instrução para inserir 10 linhas. Utiliza ligação por colunas.
#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 Vinculação
Ao usar ligação por linhas, uma aplicação define uma estrutura para cada conjunto de parâmetros. A estrutura contém um ou dois elementos para cada parâmetro. O primeiro elemento contém o valor do parâmetro, e o segundo elemento contém o buffer de comprimento/indicador. A aplicação aloca então um array destas estruturas, que contém tantos elementos quantos valores houver para cada parâmetro.
A aplicação declara o tamanho da estrutura ao driver com a instrução do atributo SQL_ATTR_PARAM_BIND_TYPE. A aplicação associa os endereços dos parâmetros na primeira estrutura do array. Assim, o driver pode efetuar o cálculo do endereço dos dados para uma determinada linha e uma coluna como
Address = Bound Address + ((Row Number - 1) * Structure Size) + Offset
onde as linhas são numeradas de 1 até ao tamanho do conjunto de parâmetros. O deslocamento, se definido, é o valor apontado pelo atributo de declaração SQL_ATTR_PARAM_BIND_OFFSET_PTR. A ilustração seguinte mostra como funciona a encadernação por filas. Os parâmetros podem ser colocados na estrutura em qualquer ordem, mas são apresentados sequencialmente para maior clareza.
O código seguinte cria uma estrutura com elementos para armazenar os valores nas colunas PartID, Descrição e Preço. Depois, aloca um array de 10 elementos destas estruturas e liga-o aos parâmetros das colunas PartID, Description e Price, usando ligação por linhas. De seguida, executa uma instrução para inserir 10 linhas.
#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;
}