Partilhar via


Função SQLBindParameter

Compatibilidade
Versão introduzida: ODBC 2.0 Conformidade com os padrões: ODBC

Resumo
SQLBindParameter associa um buffer a um marcador de parâmetro em uma instrução SQL. SQLBindParameter dá suporte à associação a um tipo de dados Unicode C, mesmo que o driver subjacente não dê suporte a dados Unicode.

Observação

Essa função substitui a função ODBC 1.0 SQLSetParam. Para obter mais informações, consulte "Comentários".

Sintaxe

  
SQLRETURN SQLBindParameter(  
      SQLHSTMT        StatementHandle,  
      SQLUSMALLINT    ParameterNumber,  
      SQLSMALLINT     InputOutputType,  
      SQLSMALLINT     ValueType,  
      SQLSMALLINT     ParameterType,  
      SQLULEN         ColumnSize,  
      SQLSMALLINT     DecimalDigits,  
      SQLPOINTER      ParameterValuePtr,  
      SQLLEN          BufferLength,  
      SQLLEN *        StrLen_or_IndPtr);  

Argumentos

Identificador de declaração
[Entrada] Identificador de instrução.

Número do parâmetro
[Entrada] Número do parâmetro, ordenado sequencialmente em ordem crescente de parâmetros, começando em 1.

InputOutputType
[Entrada] O tipo do parâmetro. Para obter mais informações, consulte "Argumento InputOutputType " em "Comentários".

ValueType
[Entrada] O tipo de dados C do parâmetro. Para obter mais informações, consulte "Argumento ValueType " em "Comentários".

ParameterType
[Entrada] O tipo de dados SQL do parâmetro. Para obter mais informações, consulte "Argumento ParameterType " em "Comentários".

ColumnSize
[Entrada] O tamanho da coluna ou expressão do marcador de parâmetro correspondente. Para obter mais informações, consulte "Argumento ColumnSize " em "Comentários".

Se o aplicativo for executado em um sistema operacional Windows de 64 bits, consulte Informações sobre ODBC de 64 bits.

DecimalDigits
[Entrada] Os dígitos decimais da coluna ou expressão do marcador de parâmetro correspondente. Para obter mais informações sobre o tamanho da coluna, consulte Tamanho da coluna, Dígitos decimais, Comprimento do octeto de transferência e Tamanho de exibição.

ParâmetroValorPtr
[Entrada diferida] Um ponteiro para um buffer para os dados do parâmetro. Para obter mais informações, consulte "Argumento ParameterValuePtr " em "Comentários".

BufferLength
[Entrada/Saída] Comprimento do buffer ParameterValuePtr em bytes. Para obter mais informações, consulte "Argumento BufferLength " em "Comentários".

Consulte Informações ODBC de 64 bits, se seu aplicativo for executado em um sistema operacional de 64 bits.

StrLen_or_IndPtr
[Entrada diferida] Um ponteiro para um buffer para o comprimento do parâmetro. Para obter mais informações, consulte "StrLen_or_IndPtr argumento" em "Comentários".

Devoluções

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR ou SQL_INVALID_HANDLE.

Diagnósticos

Quando SQLBindParameter retorna SQL_ERROR ou SQL_SUCCESS_WITH_INFO, um valor SQLSTATE associado pode ser obtido chamando SQLGetDiagRec com um HandleType de SQL_HANDLE_STMT e um Handle de StatementHandle. A tabela a seguir lista os valores SQLSTATE normalmente retornados por SQLBindParameter e explica cada um deles no contexto dessa função; a notação "(DM)" precede as descrições de SQLSTATEs retornadas pelo Gerenciador de Driver. O código de retorno associado a cada valor SQLSTATE é SQL_ERROR, a menos que indicado de outra forma.

SQLSTATE Erro Descrição
01000 Aviso geral Mensagem informativa específica do driver. (A função retorna SQL_SUCCESS_WITH_INFO.)
07006 Violação de atributo de tipo de dados restrito O tipo de dados identificado pelo argumento ValueType não pode ser convertido no tipo de dados identificado pelo argumento ParameterType . Observe que esse erro pode ser retornado por SQLExecDirect, SQLExecute ou SQLPutData em tempo de execução, em vez de por SQLBindParameter.
07009 Índice de descritor inválido (DM) O valor especificado para o argumento ParameterNumber era menor que 1.
HY000 Erro geral Ocorreu um erro para o qual não havia SQLSTATE específico e para o qual nenhum SQLSTATE específico da implementação foi definido. A mensagem de erro retornada por SQLGetDiagRec no buffer *MessageText descreve o erro e sua causa.
HY001 Erro de alocação de memória O driver não pôde alocar a memória necessária para dar suporte à execução ou conclusão da função.
HY003 Tipo de buffer de aplicativo inválido O valor especificado pelo argumento ValueType não era um tipo de dados C válido ou SQL_C_DEFAULT.
HY004 Tipo de dados SQL inválido O valor especificado para o argumento ParameterType não era um identificador de tipo de dados SQL ODBC válido nem um identificador de tipo de dados SQL específico do driver compatível com o driver.
HY009 Valor de argumento inválido (DM) O argumento ParameterValuePtr era um ponteiro nulo, o argumento StrLen_or_IndPtr era um ponteiro nulo e o argumento InputOutputType não era SQL_PARAM_OUTPUT.

(DM) SQL_PARAM_OUTPUT, em que o argumento ParameterValuePtr era um ponteiro nulo, o tipo C era char ou binário e o BufferLength (cbValueMax) era maior que 0.
HY010 Erro de sequência de função (DM) Uma função de execução assíncrona foi chamada para o identificador de conexão associado ao StatementHandle. Essa função assíncrona ainda estava em execução quando SQLBindParameter foi chamado.

(DM) SQLExecute, SQLExecDirect ou SQLMoreResults foi chamado para o StatementHandle e retornado SQL_PARAM_DATA_AVAILABLE. Essa função foi chamada antes que os dados fossem recuperados para todos os parâmetros transmitidos.

(DM) Uma função de execução assíncrona foi chamada para o StatementHandle e ainda estava em execução quando essa função foi chamada.

(DM) SQLExecute, SQLExecDirect, SQLBulkOperations ou SQLSetPos foi chamado para o StatementHandle e retornado SQL_NEED_DATA. Essa função foi chamada antes que os dados fossem enviados para todos os parâmetros ou colunas de dados em execução.
HY013 Erro de gerenciamento de memória A chamada de função não pôde ser processada porque os objetos de memória subjacentes não puderam ser acessados, possivelmente devido a condições de memória baixa.
HY021 Informações de descritor inconsistentes As informações do descritor verificadas durante uma verificação de consistência não foram consistentes. (Consulte a seção "Verificações de consistência" em SQLSetDescField.)

O valor especificado para o argumento DecimalDigits estava fora do intervalo de valores com suporte pela fonte de dados para uma coluna do tipo de dados SQL especificado pelo argumento ParameterType .
HY090 Cadeia de caracteres ou comprimento de buffer inválido (DM) O valor em BufferLength era menor que 0. (Veja a descrição do campo SQL_DESC_DATA_PTR em SQLSetDescField.)
HY104 Precisão ou valor de escala inválido O valor especificado para o argumento ColumnSize ou DecimalDigits estava fora do intervalo de valores com suporte pela fonte de dados para uma coluna do tipo de dados SQL especificado pelo argumento ParameterType .
HY105 Tipo de parâmetro inválido (DM) O valor especificado para o argumento InputOutputType era inválido. (Veja "Comentários".)
HY117 A conexão está suspensa devido ao estado desconhecido da transação. Somente funções de desconexão e somente leitura são permitidas. (DM) Para obter mais informações sobre o estado suspenso, consulte Função SQLEndTran.
HYC00 Recurso opcional não implementado O driver ou a fonte de dados não dá suporte à conversão especificada pela combinação do valor especificado para o argumento ValueType e o valor específico do driver especificado para o argumento ParameterType.

O valor especificado para o argumento ParameterType era um identificador de tipo de dados SQL ODBC válido para a versão do ODBC compatível com o driver, mas não tinha suporte do driver ou da fonte de dados.

O driver dá suporte apenas ao ODBC 2.x e o argumento ValueType foi um dos seguintes:

SQL_C_NUMERIC SQL_C_SBIGINT SQL_C_UBIGINT

e todos os tipos de dados de intervalo C listados em Tipos de Dados C no Apêndice D: Tipos de Dados.

O driver só dá suporte a versões ODBC anteriores à 3.50 e o argumento ValueType foi SQL_C_GUID.
HYT01 O tempo limite da conexão expirou O período de tempo limite da conexão expirou antes que a fonte de dados respondesse à solicitação. O período de tempo limite da conexão é definido por meio de SQLSetConnectAttr, SQL_ATTR_CONNECTION_TIMEOUT.
IM001 O driver não suporta esta função (DM) O driver associado ao StatementHandle não dá suporte à função.

Comentários

Um aplicativo chama SQLBindParameter para associar cada marcador de parâmetro em uma instrução SQL. As associações permanecem em vigor até que o aplicativo chame SQLBindParameter novamente, chame SQLFreeStmt com a opção SQL_RESET_PARAMS ou chame SQLSetDescField para definir o campo de cabeçalho SQL_DESC_COUNT do APD como 0.

Para obter mais informações sobre parâmetros, confira Parâmetros da instrução. Para obter mais informações sobre tipos de dados de parâmetro e marcadores de parâmetro, consulte Tipos de dados de parâmetro e marcadores de parâmetro no Apêndice C: Gramática SQL.

Argumento ParameterNumber

Se ParameterNumber na chamada para SQLBindParameter for maior que o valor de SQL_DESC_COUNT, SQLSetDescField será chamado para aumentar o valor de SQL_DESC_COUNT para ParameterNumber.

Argumento InputOutputType

O argumento InputOutputType especifica o tipo do parâmetro. Esse argumento define o campo SQL_DESC_PARAMETER_TYPE do IPD. Todos os parâmetros em instruções SQL que não chamam procedimentos, como instruções INSERT, são parâmetros de entrada. Os parâmetros em chamadas de procedimento podem ser parâmetros de entrada, entrada/saída ou de saída. (Um aplicativo chama SQLProcedureColumns para determinar o tipo de um parâmetro em uma chamada de procedimento; os parâmetros cujo tipo não pode ser determinado são considerados parâmetros de entrada.)

O argumento InputOutputType é um dos seguintes valores:

  • SQL_PARAM_INPUT. O parâmetro marca um parâmetro em uma instrução SQL que não chama um procedimento, como uma instrução INSERT , ou marca um parâmetro de entrada em um procedimento. Por exemplo, os parâmetros em INSERT INTO Employee VALUES (?, ?, ?) são parâmetros de entrada, enquanto os parâmetros em {call AddEmp(?, ?, ?)} podem ser, mas não necessariamente, parâmetros de entrada.

    Quando a instrução é executada, o driver envia dados para o parâmetro para a fonte de dados; o buffer *ParameterValuePtr deve conter um valor de entrada válido ou o buffer *StrLen_or_IndPtr deve conter SQL_NULL_DATA, SQL_DATA_AT_EXEC ou o resultado da macro SQL_LEN_DATA_AT_EXEC.

    Se um aplicativo não puder determinar o tipo de um parâmetro em uma chamada de procedimento, ele definirá InputOutputType como SQL_PARAM_INPUT; se a fonte de dados retornar um valor para o parâmetro, o driver o descartará.

  • SQL_PARAM_INPUT_OUTPUT. O parâmetro marca um parâmetro de entrada/saída em um procedimento. Por exemplo, o parâmetro em {call GetEmpDept(?)} é um parâmetro de entrada/saída que aceita o nome de um funcionário e retorna o nome do departamento do funcionário.

    Quando a instrução é executada, o driver envia dados para o parâmetro para a fonte de dados; o buffer *ParameterValuePtr deve conter um valor de entrada válido ou o buffer *StrLen_or_IndPtr deve conter SQL_NULL_DATA, SQL_DATA_AT_EXEC ou o resultado da macro SQL_LEN_DATA_AT_EXEC. Depois que a instrução é executada, o driver retorna dados do parâmetro para o aplicativo; Se a fonte de dados não retornar um valor para um parâmetro de entrada/saída, o driver definirá o buffer *StrLen_or_IndPtr como SQL_NULL_DATA.

    Observação

    Quando um aplicativo ODBC 1.0 chama SQLSetParam em um driver ODBC 2.0, o Gerenciador de Driver converte isso em uma chamada para SQLBindParameter na qual o argumento InputOutputType é definido como SQL_PARAM_INPUT_OUTPUT.

  • SQL_PARAM_OUTPUT. O parâmetro marca o valor retornado de um procedimento ou um parâmetro de saída em um procedimento; Em ambos os casos, eles são conhecidos como parâmetros de saída. Por exemplo, o parâmetro em {?=call GetNextEmpID} é um parâmetro de saída que retorna a próxima ID do funcionário.

    Depois que a instrução é executada, o driver retorna dados para o parâmetro para o aplicativo, a menos que os argumentos ParameterValuePtr e StrLen_or_IndPtr sejam ponteiros nulos, caso em que o driver descarta o valor de saída. Se a fonte de dados não retornar um valor para um parâmetro de saída, o driver definirá o buffer *StrLen_or_IndPtr como SQL_NULL_DATA.

  • SQL_PARAM_INPUT_OUTPUT_STREAM. Indica que um parâmetro de entrada/saída deve ser transmitido. SQLGetData pode ler valores de parâmetro em partes. BufferLength é ignorado porque o comprimento do buffer será determinado na chamada de SQLGetData. O valor do buffer de StrLen_or_IndPtr deve conter SQL_NULL_DATA, SQL_DEFAULT_PARAM, SQL_DATA_AT_EXEC ou o resultado da macro SQL_LEN_DATA_AT_EXEC. Um parâmetro deve ser associado como um parâmetro de dados em execução (DAE) na entrada se for transmitido na saída. ParameterValuePtr pode ser qualquer valor de ponteiro não nulo que será retornado por SQLParamData como o token definido pelo usuário cujo valor foi passado com ParameterValuePtr para entrada e saída. Para obter mais informações, consulte Recuperando parâmetros de saída usando SQLGetData.

  • SQL_PARAM_OUTPUT_STREAM. O mesmo que SQL_PARAM_INPUT_OUTPUT_STREAM, para um parâmetro de saída. * StrLen_or_IndPtr é ignorado na entrada.

A tabela a seguir lista diferentes combinações de InputOutputType e *StrLen_or_IndPtr:

InputOutputType *StrLen_or_IndPtr Resultado Observação sobre ParameterValuePtr
SQL_PARAM_INPUT SQL_LEN_DATA_AT_EXEC (len) ou SQL_DATA_AT_EXEC Entrada em peças ParameterValuePtr pode ser qualquer valor de ponteiro que será retornado por SQLParamData como o token definido pelo usuário cujo valor foi passado com ParameterValuePtr.
SQL_PARAM_INPUT Não SQL_LEN_DATA_AT_EXEC(len) ou SQL_DATA_AT_EXEC Buffer associado de entrada ParameterValuePtr é o endereço do buffer de entrada.
SQL_PARAM_OUTPUT Ignorado na entrada. Buffer associado de saída ParameterValuePtr é o endereço do buffer de saída.
SQL_PARAM_OUTPUT_STREAM Ignorado na entrada. Saída transmitida ParameterValuePtr pode ser qualquer valor de ponteiro, que será retornado por SQLParamData como o token definido pelo usuário cujo valor foi passado com ParameterValuePtr.
SQL_PARAM_INPUT_OUTPUT SQL_LEN_DATA_AT_EXEC (len) ou SQL_DATA_AT_EXEC Entrada em partes e buffer de saída ParameterValuePtr é o endereço do buffer de saída, que também será retornado por SQLParamData como o token definido pelo usuário cujo valor foi passado com ParameterValuePtr.
SQL_PARAM_INPUT_OUTPUT Não SQL_LEN_DATA_AT_EXEC(len) ou SQL_DATA_AT_EXEC Buffer associado de entrada e buffer associado de saída ParameterValuePtr é o endereço do buffer de entrada/saída compartilhado.
SQL_PARAM_INPUT_OUTPUT_STREAM SQL_LEN_DATA_AT_EXEC (len) ou SQL_DATA_AT_EXEC Entrada em partes e saída transmitida ParameterValuePtr pode ser qualquer valor de ponteiro não nulo, que será retornado por SQLParamData como o token definido pelo usuário cujo valor foi passado com ParameterValuePtr para entrada e saída.

Observação

O driver deve decidir quais tipos de SQL são permitidos quando um aplicativo associa um parâmetro de saída ou de entrada-saída conforme transmitido. O gerenciador de driver não gerará um erro para um tipo SQL inválido.

Argumento ValueType

O argumento ValueType especifica o tipo de dados C do parâmetro. Esse argumento define os campos SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE e SQL_DESC_DATETIME_INTERVAL_CODE do APD. Esse deve ser um dos valores na seção Tipos de Dados C do Apêndice D: Tipos de Dados.

Se o argumento ValueType for um dos tipos de dados de intervalo, o campo SQL_DESC_TYPE do registro ParameterNumber do APD será definido como SQL_INTERVAL, o campo SQL_DESC_CONCISE_TYPE do APD será definido como o tipo de dados de intervalo conciso e o campo SQL_DESC_DATETIME_INTERVAL_CODE do registro ParameterNumber será definido como um subcódigo para o tipo de dados de intervalo específico. (Veja Apêndice D: Tipos de dados.) A precisão de entrelinha de intervalo padrão (2) e a precisão de segundos de intervalo padrão (6), conforme definido nos campos SQL_DESC_DATETIME_INTERVAL_PRECISION e SQL_DESC_PRECISION do APD, respectivamente, são usadas para os dados. Se a precisão padrão não for apropriada, o aplicativo deverá definir explicitamente o campo descritor por uma chamada para SQLSetDescField ou SQLSetDescRec.

Se o argumento ValueType for um dos tipos de dados datetime, o campo SQL_DESC_TYPE do registro ParameterNumber do APD será definido como SQL_DATETIME, o campo SQL_DESC_CONCISE_TYPE do registro ParameterNumber do APD será definido como o tipo de dados conciso datetime C e o campo SQL_DESC_DATETIME_INTERVAL_CODE do registro ParameterNumber será definido como um subcódigo para o tipo de dados datetime específico. (Veja Apêndice D: Tipos de dados.)

Se o argumento ValueType for um tipo de dados SQL_C_NUMERIC, a precisão padrão (que é definida pelo driver) e a escala padrão (0), conforme definido nos campos SQL_DESC_PRECISION e SQL_DESC_SCALE do APD, serão usadas para os dados. Se a precisão ou escala padrão não for apropriada, o aplicativo deverá definir explicitamente o campo descritor por uma chamada para SQLSetDescField ou SQLSetDescRec.

SQL_C_DEFAULT especifica que o valor do parâmetro seja transferido do tipo de dados C padrão para o tipo de dados SQL especificado com ParameterType.

Você também pode especificar um tipo de dados C estendido. Para obter mais informações, consulte Tipos de dados C em ODBC.

Para obter mais informações, consulte Tipos de dados C padrão, Convertendo dados de tipos de dados C para SQL e Convertendo dados de tipos de dados SQL para C no Apêndice D: Tipos de dados.

Argumento ParameterType

Esse deve ser um dos valores listados na seção Tipos de Dados SQL do Apêndice D: Tipos de Dados ou deve ser um valor específico do driver. Esse argumento define os campos SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE e SQL_DESC_DATETIME_INTERVAL_CODE do IPD.

Se o argumento ParameterType for um dos identificadores de data e hora, o campo SQL_DESC_TYPE do IPD será definido como SQL_DATETIME, o campo SQL_DESC_CONCISE_TYPE do IPD será definido como o tipo de dados SQL de data e hora conciso e o campo SQL_DESC_DATETIME_INTERVAL_CODE será definido como o valor de subcódigo de data e hora apropriado.

Se ParameterType for um dos identificadores de intervalo, o campo SQL_DESC_TYPE do IPD será definido como SQL_INTERVAL, o campo SQL_DESC_CONCISE_TYPE do IPD será definido como o tipo de dados de intervalo SQL conciso e o campo SQL_DESC_DATETIME_INTERVAL_CODE do IPD será definido como o subcódigo de intervalo apropriado. O campo SQL_DESC_DATETIME_INTERVAL_PRECISION do IPD é definido como a precisão de entrelinha do intervalo e o campo SQL_DESC_PRECISION é definido como a precisão de segundos de intervalo, se aplicável. Se o valor padrão de SQL_DESC_DATETIME_INTERVAL_PRECISION ou SQL_DESC_PRECISION não for apropriado, o aplicativo deverá defini-lo explicitamente chamando SQLSetDescField. Para obter mais informações sobre qualquer um desses campos, consulte SQLSetDescField.

Se o argumento ValueType for um tipo de dados SQL_NUMERIC, a precisão padrão (que é definida pelo driver) e a escala padrão (0), conforme definido nos campos SQL_DESC_PRECISION e SQL_DESC_SCALE do IPD, serão usadas para os dados. Se a precisão ou escala padrão não for apropriada, o aplicativo deverá definir explicitamente o campo descritor por uma chamada para SQLSetDescField ou SQLSetDescRec.

Para obter informações sobre como os dados são convertidos, consulte Convertendo dados de tipos de dados C para SQL e Convertendo dados de tipos de dados SQL para C no Apêndice D: Tipos de dados.

Argumento ColumnSize

O argumento ColumnSize especifica o tamanho da coluna ou expressão que corresponde ao marcador de parâmetro, o comprimento desses dados ou ambos. Esse argumento define campos diferentes do IPD, dependendo do tipo de dados SQL (o argumento ParameterType ). As seguintes regras se aplicam a esse mapeamento:

  • Se ParameterType for SQL_CHAR, SQL_VARCHAR, SQL_LONGVARCHAR, SQL_BINARY, SQL_VARBINARY, SQL_LONGVARBINARY ou um dos tipos de dados SQL concisos de data/hora ou intervalo, o campo SQL_DESC_LENGTH do IPD será definido como o valor de ColumnSize. (Para obter mais informações, consulte o Seção Tamanho da coluna, dígitos decimais, comprimento do octeto de transferência e tamanho de exibição no Apêndice D: Tipos de dados.)

  • Se ParameterType for SQL_DECIMAL, SQL_NUMERIC, SQL_FLOAT, SQL_REAL ou SQL_DOUBLE, o campo SQL_DESC_PRECISION do IPD será definido como o valor de ColumnSize.

  • Para outros tipos de dados, o argumento ColumnSize é ignorado.

Para obter mais informações, consulte "Passando valores de parâmetro" e SQL_DATA_AT_EXEC em "StrLen_or_IndPtr argumento".

Argumento DecimalDigits

Se ParameterType for SQL_TYPE_TIME, SQL_TYPE_TIMESTAMP, SQL_INTERVAL_SECOND, SQL_INTERVAL_DAY_TO_SECOND, SQL_INTERVAL_HOUR_TO_SECOND ou SQL_INTERVAL_MINUTE_TO_SECOND, o campo SQL_DESC_PRECISION do IPD será definido como DecimalDigits. Se ParameterType for SQL_NUMERIC ou SQL_DECIMAL, o campo SQL_DESC_SCALE do IPD será definido como DecimalDigits. Para todos os outros tipos de dados, o argumento DecimalDigits é ignorado.

Argumento ParameterValuePtr

O argumento ParameterValuePtr aponta para um buffer que, quando SQLExecute ou SQLExecDirect é chamado, contém os dados reais do parâmetro. Os dados devem estar no formato especificado pelo argumento ValueType . Esse argumento define o campo SQL_DESC_DATA_PTR do APD. Um aplicativo pode definir o argumento ParameterValuePtr como um ponteiro nulo, desde que *StrLen_or_IndPtr seja SQL_NULL_DATA ou SQL_DATA_AT_EXEC. (Isso se aplica apenas a parâmetros de entrada ou entrada/saída.)

Se *StrLen_or_IndPtr for o resultado da macro ou SQL_DATA_AT_EXEC SQL_LEN_DATA_AT_EXEC(comprimento), ParameterValuePtr será um valor de ponteiro definido pelo aplicativo associado ao parâmetro. Ele é retornado ao aplicativo por meio de SQLParamData. Por exemplo, ParameterValuePtr pode ser um token diferente de zero, como um número de parâmetro, um ponteiro para dados ou um ponteiro para uma estrutura que o aplicativo usou para associar parâmetros de entrada. No entanto, observe que, se o parâmetro for um parâmetro de entrada/saída, ParameterValuePtr deverá ser um ponteiro para um buffer em que o valor de saída será armazenado. Se o valor no atributo de instrução SQL_ATTR_PARAMSET_SIZE for maior que 1, o aplicativo poderá usar o valor apontado pelo atributo de instrução SQL_ATTR_PARAMS_PROCESSED_PTR junto com o argumento ParameterValuePtr . Por exemplo, ParameterValuePtr pode apontar para uma matriz de valores e o aplicativo pode usar o valor apontado por SQL_ATTR_PARAMS_PROCESSED_PTR para recuperar o valor correto da matriz. Para obter mais informações, consulte "Passando valores de parâmetro" mais adiante nesta seção.

Se o argumento InputOutputType for SQL_PARAM_INPUT_OUTPUT ou SQL_PARAM_OUTPUT, ParameterValuePtr apontará para um buffer no qual o driver retorna o valor de saída. Se o procedimento retornar um ou mais conjuntos de resultados, não haverá garantia de que o buffer *ParameterValuePtr seja definido até que todos os conjuntos de resultados/contagens de linhas tenham sido processados. Se o buffer não for definido até que o processamento seja concluído, os parâmetros de saída e os valores retornados não estarão disponíveis até que SQLMoreResults retorne SQL_NO_DATA. Chamar SQLCloseCursor ou SQLFreeStmt com uma Option de SQL_CLOSE fará com que esses valores sejam descartados.

Se o valor no atributo de instrução SQL_ATTR_PARAMSET_SIZE for maior que 1, ParameterValuePtr apontará para uma matriz. Uma única instrução SQL processa a matriz completa de valores de entrada para um parâmetro de entrada ou entrada/saída e retorna uma matriz de valores de saída para um parâmetro de entrada/saída ou saída.

Argumento BufferLength

Para caracteres e dados binários C, o argumento BufferLength especifica o comprimento do buffer *ParameterValuePtr (se for um único elemento) ou o comprimento de um elemento na matriz *ParameterValuePtr (se o valor no atributo de instrução SQL_ATTR_PARAMSET_SIZE for maior que 1). Esse argumento define o campo de registro SQL_DESC_OCTET_LENGTH do APD. Se o aplicativo especificar vários valores, BufferLength será usado para determinar o local dos valores na matriz *ParameterValuePtr , tanto na entrada quanto na saída. Para parâmetros de entrada/saída e saída, ele é usado para determinar se os dados C binários e de caractere devem ser truncados na saída:

  • Para dados de caractere C, se o número de bytes disponíveis para retorno for maior ou igual a BufferLength, os dados em *ParameterValuePtr serão truncados para BufferLength menos o comprimento de um caractere de terminação nula e serão terminados em nulo pelo driver.

  • Para dados binários C, se o número de bytes disponíveis para retorno for maior que BufferLength, os dados em *ParameterValuePtr serão truncados para bytes BufferLength.

Para todos os outros tipos de dados C, o argumento BufferLength é ignorado. O comprimento do buffer *ParameterValuePtr (se for um único elemento) ou o comprimento de um elemento na matriz *ParameterValuePtr (se o aplicativo chamar SQLSetStmtAttr com um argumento Attribute de SQL_ATTR_PARAMSET_SIZE para especificar vários valores para cada parâmetro) é considerado o comprimento do tipo de dados C.

Para parâmetros de saída transmitida ou entrada/saída transmitida, o argumento BufferLength é ignorado porque o comprimento do buffer é especificado em SQLGetData.

Observação

Quando um aplicativo ODBC 1.0 chama SQLSetParam em um ODBC 3.x , o Gerenciador de Driver converte isso em uma chamada para SQLBindParameter na qual o argumento BufferLength é sempre SQL_SETPARAM_VALUE_MAX. Como o Gerenciador de Driver retorna um erro se um ODBC 3.x define BufferLength como SQL_SETPARAM_VALUE_MAX, um ODBC 3.x pode usar isso para determinar quando ele é chamado por um aplicativo ODBC 1.0.

Observação

Em SQLSetParam, a maneira como um aplicativo especifica o comprimento do buffer *ParameterValuePtr para que o driver possa retornar dados binários ou de caractere e a maneira como um aplicativo envia uma matriz de valores de parâmetro binário ou de caractere para o driver são definidos pelo driver.

StrLen_or_IndPtr Argumento

O argumento StrLen_or_IndPtr aponta para um buffer que, quando SQLExecute ou SQLExecDirect é chamado, contém um dos seguintes. (Esse argumento define os campos de registro SQL_DESC_OCTET_LENGTH_PTR e SQL_DESC_INDICATOR_PTR dos ponteiros de parâmetro do aplicativo.)

  • O comprimento do valor do parâmetro armazenado em *ParameterValuePtr. Isso é ignorado, exceto para caracteres ou dados binários C.

  • SQL_NTS. O valor do parâmetro é uma cadeia de caracteres terminada em nulo.

  • SQL_NULL_DATA. O valor do parâmetro é NULL.

  • SQL_DEFAULT_PARAM. Um procedimento é usar o valor padrão de um parâmetro, em vez de um valor recuperado do aplicativo. Esse valor é válido somente em um procedimento chamado na sintaxe canônica ODBC e, em seguida, somente se o argumento InputOutputType for SQL_PARAM_INPUT, SQL_PARAM_INPUT_OUTPUT ou SQL_PARAM_INPUT_OUTPUT_STREAM. Quando *StrLen_or_IndPtr é SQL_DEFAULT_PARAM, os argumentos ValueType, ParameterType, ColumnSize, DecimalDigits, BufferLength e ParameterValuePtr são ignorados para parâmetros de entrada e são usados apenas para definir o valor do parâmetro de saída para parâmetros de entrada/saída.

  • O resultado da macro SQL_LEN_DATA_AT_EXEC(comprimento). Os dados do parâmetro serão enviados com SQLPutData. Se o argumento ParameterType for SQL_LONGVARBINARY, SQL_LONGVARCHAR ou um tipo de dados longo específico da fonte de dados e o driver retornar "Y" para o tipo de informação SQL_NEED_LONG_DATA_LEN em SQLGetInfo, length será o número de bytes de dados a serem enviados para o parâmetro; caso contrário, length deverá ser um valor não negativo e será ignorado. Para obter mais informações, consulte "Passando valores de parâmetro", mais adiante nesta seção.

    Por exemplo, para especificar que 10.000 bytes de dados serão enviados com SQLPutData em uma ou mais chamadas, para um parâmetro SQL_LONGVARCHAR, um aplicativo define *StrLen_or_IndPtr como SQL_LEN_DATA_AT_EXEC(10000).

  • SQL_DATA_AT_EXEC. Os dados do parâmetro serão enviados com SQLPutData. Esse valor é usado por aplicativos ODBC 1.0 quando eles chamam ODBC 3.x drivers. Para obter mais informações, consulte "Passando valores de parâmetro", mais adiante nesta seção.

Se StrLen_or_IndPtr for um ponteiro nulo, o driver pressupõe que todos os valores de parâmetro de entrada não são NULL e que os dados de caractere e binários são terminados em nulo. Se InputOutputType for SQL_PARAM_OUTPUT ou SQL_PARAM_OUTPUT_STREAM e ParameterValuePtr e StrLen_or_IndPtr forem ponteiros nulos, o driver descartará o valor de saída.

Observação

Os desenvolvedores de aplicativos são fortemente desencorajados a especificar um ponteiro nulo para StrLen_or_IndPtr quando o tipo de dados do parâmetro é SQL_C_BINARY. Para garantir que um driver não trunque inesperadamente SQL_C_BINARY dados, StrLen_or_IndPtr deve conter um ponteiro para um valor de comprimento válido.

Se o argumento InputOutputType for SQL_PARAM_INPUT_OUTPUT, SQL_PARAM_OUTPUT, SQL_PARAM_INPUT_OUTPUT_STREAM ou SQL_PARAM_OUTPUT_STREAM, StrLen_or_IndPtr apontará para um buffer no qual o driver retorna SQL_NULL_DATA, o número de bytes disponíveis para retornar em *ParameterValuePtr (excluindo o byte de terminação nula de dados de caractere) ou SQL_NO_TOTAL (se o número de bytes disponíveis para retornar não puder ser determinado). Se o procedimento retornar um ou mais conjuntos de resultados, não haverá garantia de que o buffer *StrLen_or_IndPtr seja definido até que todos os resultados tenham sido buscados.

Se o valor no atributo de instrução SQL_ATTR_PARAMSET_SIZE for maior que 1, StrLen_or_IndPtr apontará para uma matriz de valores SQLLEN. Eles podem ser qualquer um dos valores listados anteriormente nesta seção e são processados com uma única instrução SQL.

Passando valores de parâmetro

Um aplicativo pode passar o valor de um parâmetro no buffer *ParameterValuePtr ou com uma ou mais chamadas para SQLPutData. Os parâmetros cujos dados são passados com SQLPutData são conhecidos como parâmetros de dados em execução . Normalmente, eles são usados para enviar dados para parâmetros SQL_LONGVARBINARY e SQL_LONGVARCHAR e podem ser misturados com outros parâmetros.

Para passar valores de parâmetro, um aplicativo executa a seguinte sequência de etapas:

  1. Chama SQLBindParameter para cada parâmetro para associar buffers para o valor do parâmetro (argumento ParameterValuePtr ) e comprimento/indicador (argumento StrLen_or_IndPtr ). Para parâmetros de dados em execução, ParameterValuePtr é um valor de ponteiro definido pelo aplicativo, como um número de parâmetro ou um ponteiro para dados. O valor será retornado posteriormente e poderá ser usado para identificar o parâmetro.

  2. Coloca valores para parâmetros de entrada e entrada/saída nos buffers *ParameterValuePtr e *StrLen_or_IndPtr :

    • Para parâmetros normais, o aplicativo coloca o valor do parâmetro no buffer *ParameterValuePtr e o comprimento desse valor no buffer *StrLen_or_IndPtr . Para obter mais informações, consulte Definindo valores de parâmetro.

    • Para parâmetros de dados em execução, o aplicativo coloca o resultado da macro SQL_LEN_DATA_AT_EXEC (comprimento) (ao chamar um driver ODBC 2.0) no buffer *StrLen_or_IndPtr .

  3. Chama SQLExecute ou SQLExecDirect para executar a instrução SQL.

    • Se não houver parâmetros de dados em execução, o processo será concluído.

    • Se houver parâmetros de dados em execução, a função retornará SQL_NEED_DATA.

  4. Chama SQLParamData para recuperar o valor definido pelo aplicativo especificado no argumento ParameterValuePtr de SQLBindParameter para o primeiro parâmetro de dados em execução a ser processado. SQLParamData retorna SQL_NEED_DATA.

    Observação

    Embora os parâmetros de dados em execução sejam semelhantes a colunas de dados em execução, o valor retornado por SQLParamData é diferente para cada um. Os parâmetros de dados em execução são parâmetros em uma instrução SQL para os quais os dados serão enviados com SQLPutData quando a instrução for executada com SQLExecDirect ou SQLExecute. Eles estão associados a SQLBindParameter. O valor retornado por SQLParamData é um valor de ponteiro passado para SQLBindParameter no argumento ParameterValuePtr . As colunas de dados em execução são colunas em um conjunto de linhas para as quais os dados serão enviados com SQLPutData quando uma linha for atualizada ou adicionada com SQLBulkOperations ou atualizada com SQLSetPos. Eles estão associados a SQLBindCol. O valor retornado por SQLParamData é o endereço da linha no buffer *TargetValuePtr (definido por uma chamada para SQLBindCol) que está sendo processado.

  5. Chama SQLPutData uma ou mais vezes para enviar dados para o parâmetro. Mais de uma chamada será necessária se o valor de dados for maior que o buffer *ParameterValuePtr especificado em SQLPutData; várias chamadas para SQLPutData para o mesmo parâmetro são permitidas somente ao enviar dados de caractere C para uma coluna com um tipo de dados de caractere, binário ou específico da fonte de dados ou ao enviar dados binários C para uma coluna com um caractere, binário ou tipo de dados específico da fonte de dados.

  6. Chama SQLParamData novamente para sinalizar que todos os dados foram enviados para o parâmetro.

    • Se houver mais parâmetros de dados em execução, SQLParamData retornará SQL_NEED_DATA e o valor definido pelo aplicativo para o próximo parâmetro de dados em execução a ser processado. O aplicativo repete as etapas 4 e 5.

    • Se não houver mais parâmetros de dados em execução, o processo será concluído. Se a instrução foi executada com êxito, SQLParamData retornará SQL_SUCCESS ou SQL_SUCCESS_WITH_INFO; se a execução falhar, ele retornará SQL_ERROR. Neste ponto, SQLParamData pode retornar qualquer SQLSTATE que possa ser retornado pela função usada para executar a instrução (SQLExecDirect ou SQLExecute).

      Os valores de saída para quaisquer parâmetros de entrada/saída ou saída estão disponíveis nos buffers *ParameterValuePtr e *StrLen_or_IndPtr depois que o aplicativo recupera todos os conjuntos de resultados gerados pela instrução.

Chamar SQLExecute ou SQLExecDirect coloca a instrução em um estado SQL_NEED_DATA. Neste ponto, o aplicativo pode chamar apenas SQLCancel, SQLGetDiagField, SQLGetDiagRec, SQLGetFunctions, SQLParamData ou SQLPutData com a instrução ou o identificador de conexão associado à instrução. Se ele chamar qualquer outra função com a instrução ou a conexão associada à instrução, a função retornará SQLSTATE HY010 (erro de sequência de função). A instrução deixa o estado SQL_NEED_DATA quando SQLParamData ou SQLPutData retorna um erro, SQLParamData retorna SQL_SUCCESS ou SQL_SUCCESS_WITH_INFO ou a instrução é cancelada.

Se o aplicativo chamar SQLCancel enquanto o driver ainda precisar de dados para parâmetros de dados em execução, o driver cancelará a execução da instrução; o aplicativo poderá chamar SQLExecute ou SQLExecDirect novamente.

Recuperando parâmetros de saída transmitidos

Quando um aplicativo define InputOutputType como SQL_PARAM_INPUT_OUTPUT_STREAM ou SQL_PARAM_OUTPUT_STREAM, o valor do parâmetro de saída deve ser recuperado por uma ou mais chamadas para SQLGetData. Quando o driver tiver um valor de parâmetro de saída transmitido para retornar ao aplicativo, ele retornará SQL_PARAM_DATA_AVAILABLE em resposta a uma chamada para as seguintes funções: SQLMoreResults, SQLExecute e SQLExecDirect. Um aplicativo chama SQLParamData para determinar qual valor de parâmetro está disponível.

Para obter mais informações sobre parâmetros de saída SQL_PARAM_DATA_AVAILABLE e transmitidos, consulte Recuperando parâmetros de saída usando SQLGetData.

Usar matrizes de parâmetros

Quando um aplicativo prepara uma instrução com marcadores de parâmetro e passa uma matriz de parâmetros, há duas maneiras diferentes de executar isso. Uma maneira é o driver confiar nos recursos de processamento de matriz do back-end, caso em que toda a instrução com a matriz de parâmetros é tratada como uma unidade atômica. Oracle é um exemplo de uma fonte de dados que suporta recursos de processamento de array. Outra maneira de implementar esse recurso é o driver gerar um lote de instruções SQL, uma instrução SQL para cada conjunto de parâmetros na matriz de parâmetros e executar o lote. Matrizes de parâmetros não podem ser usadas com uma instrução UPDATE WHERE CURRENT OF .

Quando uma matriz de parâmetros é processada, conjuntos de resultados/contagens de linhas individuais (um para cada conjunto de parâmetros) podem estar disponíveis ou conjuntos de resultados/contagens de linhas podem ser agrupados em um. A opção SQL_PARAM_ARRAY_ROW_COUNTS em SQLGetInfo indica se as contagens de linhas estão disponíveis para cada conjunto de parâmetros (SQL_PARC_BATCH) ou se apenas uma contagem de linhas está disponível (SQL_PARC_NO_BATCH).

A opção SQL_PARAM_ARRAY_SELECTS em SQLGetInfo indica se um conjunto de resultados está disponível para cada conjunto de parâmetros (SQL_PAS_BATCH) ou se apenas um conjunto de resultados está disponível (SQL_PAS_NO_BATCH). Se o driver não permitir que uma instrução de geração de conjunto de resultados seja executada com uma matriz de parâmetros, SQL_PARAM_ARRAY_SELECTS retornará SQL_PAS_NO_SELECT.

Para obter mais informações, consulte Função SQLGetInfo.

Para dar suporte a matrizes de parâmetros, o atributo de instrução SQL_ATTR_PARAMSET_SIZE é definido para especificar o número de valores para cada parâmetro. Se o campo for maior que 1, os campos SQL_DESC_DATA_PTR, SQL_DESC_INDICATOR_PTR e SQL_DESC_OCTET_LENGTH_PTR do APD deverão apontar para matrizes. A cardinalidade de cada matriz é igual ao valor de SQL_ATTR_PARAMSET_SIZE.

O campo SQL_DESC_ROWS_PROCESSED_PTR do APD aponta para um buffer que contém o número de conjuntos de parâmetros que foram processados, incluindo conjuntos de erros. À medida que cada conjunto de parâmetros é processado, o driver armazena um novo valor no buffer. Nenhum número será retornado se este for um ponteiro nulo. Quando matrizes de parâmetros são usadas, o valor apontado pelo campo SQL_DESC_ROWS_PROCESSED_PTR do APD é preenchido mesmo que SQL_ERROR seja retornado pela função de configuração. Se SQL_NEED_DATA for retornado, o valor apontado pelo campo SQL_DESC_ROWS_PROCESSED_PTR do APD será definido como o conjunto de parâmetros que está sendo processado.

O que ocorre quando uma matriz de parâmetros é associada e uma instrução UPDATE WHERE CURRENT OF é executada é definida pelo driver.

Associação de parâmetro em coluna

Na associação em colunas, o aplicativo associa matrizes separadas de parâmetros e comprimentos/indicadores a cada parâmetro.

Para usar a associação em colunas, o aplicativo primeiro define o atributo de instrução SQL_ATTR_PARAM_BIND_TYPE como SQL_PARAM_BIND_BY_COLUMN. (Esse é o padrão.) Para cada coluna a ser associada, o aplicativo executa as seguintes etapas:

  1. Aloca uma matriz de buffer de parâmetro.

  2. Aloca uma matriz de buffers de comprimento/indicador.

    Observação

    Se o aplicativo gravar diretamente nos descritores quando a associação em colunas for usada, matrizes separadas poderão ser usadas para dados de comprimento e indicador.

  3. Chama SQLBindParameter com os seguintes argumentos:

    • ValueType é o tipo C de um único elemento na matriz de buffer de parâmetro.

    • ParameterType é o tipo SQL do parâmetro.

    • ParameterValuePtr é o endereço da matriz de buffer de parâmetro.

    • BufferLength é o tamanho de um único elemento na matriz de buffer de parâmetro. O argumento BufferLength é ignorado quando os dados são dados de comprimento fixo.

    • StrLen_or_IndPtr é o endereço da matriz de comprimento/indicador.

Para obter mais informações sobre como essas informações são usadas, consulte "Argumento ParameterValuePtr" em "Comentários", mais adiante nesta seção. Para obter mais informações sobre a associação de parâmetros em colunas, consulte Matrizes de associação de parâmetros.

Associação de parâmetro de linha a linha

Na associação em linha, o aplicativo define uma estrutura que contém buffers de parâmetro e comprimento/indicador para cada parâmetro a ser associado.

Para usar a associação de linha, o aplicativo executa as seguintes etapas:

  1. Define uma estrutura para manter um único conjunto de parâmetros (incluindo buffers de parâmetro e comprimento/indicador) e aloca uma matriz dessas estruturas.

    Observação

    Se o aplicativo gravar diretamente nos descritores quando a associação de linha for usada, campos separados poderão ser usados para dados de comprimento e indicador.

  2. Define o atributo de instrução SQL_ATTR_PARAM_BIND_TYPE para o tamanho da estrutura que contém um único conjunto de parâmetros ou para o tamanho de uma instância de um buffer no qual os parâmetros serão associados. O comprimento deve incluir espaço para todos os parâmetros associados e qualquer preenchimento da estrutura ou buffer, para garantir que, quando o endereço de um parâmetro associado for incrementado com o comprimento especificado, o resultado aponte para o início do mesmo parâmetro na próxima linha. Quando você usa o operador sizeof no ANSI C, esse comportamento é garantido.

  3. Chama SQLBindParameter com os seguintes argumentos para cada parâmetro a ser associado:

    • ValueType é o tipo do membro do buffer de parâmetro a ser associado à coluna.

    • ParameterType é o tipo SQL do parâmetro.

    • ParameterValuePtr é o endereço do membro do buffer de parâmetro no primeiro elemento de matriz.

    • BufferLength é o tamanho do membro do buffer de parâmetro.

    • StrLen_or_IndPtr é o endereço do membro de comprimento/indicador a ser vinculado.

Para obter mais informações sobre como essas informações são usadas, consulte "Argumento ParameterValuePtr ", mais adiante nesta seção. Para obter mais informações sobre a associação de parâmetros em linha, consulte as matrizes de associação de parâmetros.

Informações de erro

Se um driver não implementar matrizes de parâmetros como lotes (a opção SQL_PARAM_ARRAY_ROW_COUNTS é igual a SQL_PARC_NO_BATCH), as situações de erro serão tratadas como se uma instrução tivesse sido executada. Se o driver implementar matrizes de parâmetros como lotes, um aplicativo poderá usar o campo de cabeçalho SQL_DESC_ARRAY_STATUS_PTR do IPD para determinar qual parâmetro de uma instrução SQL ou qual parâmetro em uma matriz de parâmetros fez com que SQLExecDirect ou SQLExecute retornasse um erro. Este campo contém informações de status para cada linha de valores de parâmetro. Se o campo indicar que ocorreu um erro, os campos na estrutura de dados de diagnóstico indicarão a linha e o número do parâmetro que falhou. O número de elementos na matriz será definido pelo campo de cabeçalho SQL_DESC_ARRAY_SIZE no APD, que pode ser definido pelo atributo de instrução SQL_ATTR_PARAMSET_SIZE.

Observação

O campo de cabeçalho SQL_DESC_ARRAY_STATUS_PTR no APD é usado para ignorar parâmetros. Para obter mais informações sobre como ignorar parâmetros, consulte a próxima seção, "Ignorando um conjunto de parâmetros".

Quando SQLExecute ou SQLExecDirect retorna SQL_ERROR, os elementos na matriz apontados pelo campo SQL_DESC_ARRAY_STATUS_PTR no IPD conterão SQL_PARAM_ERROR, SQL_PARAM_SUCCESS, SQL_PARAM_SUCCESS_WITH_INFO, SQL_PARAM_UNUSED ou SQL_PARAM_DIAG_UNAVAILABLE.

Para cada elemento nessa matriz, a estrutura de dados de diagnóstico contém um ou mais registros de status. O campo SQL_DIAG_ROW_NUMBER da estrutura indica o número da linha dos valores de parâmetro que causaram o erro. Se for possível determinar o parâmetro específico em uma linha de parâmetros que causou o erro, o número do parâmetro será inserido no campo SQL_DIAG_COLUMN_NUMBER.

SQL_PARAM_UNUSED é inserido quando um parâmetro não foi usado porque ocorreu um erro em um parâmetro anterior que forçou SQLExecute ou SQLExecDirect a anular. Por exemplo, se houver 50 parâmetros e ocorrer um erro durante a execução do quadragésimo conjunto de parâmetros que fez com que SQLExecute ou SQLExecDirect fosse anulado, SQL_PARAM_UNUSED será inserido na matriz de status para os parâmetros 41 a 50.

SQL_PARAM_DIAG_UNAVAILABLE é inserido quando o driver trata matrizes de parâmetros como uma unidade monolítica, portanto, ele não gera esse nível de parâmetro individual de informações de erro.

Alguns erros no processamento de um único conjunto de parâmetros fazem com que o processamento dos conjuntos subsequentes de parâmetros na matriz seja interrompido. Outros erros não afetam o processamento de parâmetros subseqüentes. Quais erros interromperão o processamento são definidos pelo driver. Se o processamento não for interrompido, todos os parâmetros na matriz serão processados, SQL_SUCCESS_WITH_INFO será retornado como resultado do erro e o buffer definido por SQL_ATTR_PARAMS_PROCESSED_PTR será definido como o número total de conjuntos de parâmetros processados (conforme definido pelo atributo de instrução SQL_ATTR_PARAMSET_SIZE), que inclui conjuntos de erros.

Cuidado

O comportamento do ODBC quando ocorre um erro no processamento de uma matriz de parâmetros é diferente no ODBC 3.x do que no ODBC 2.x. No ODBC 2.x, a função retornou SQL_ERROR e o processamento cessou. O buffer apontado pelo argumento pirow de SQLParamOptions continha o número da linha de erro. No ODBC 3.x, a função retorna SQL_SUCCESS_WITH_INFO e o processamento pode parar ou continuar. Se continuar, o buffer especificado por SQL_ATTR_PARAMS_PROCESSED_PTR será definido como o valor de todos os parâmetros processados, incluindo aqueles que resultaram em um erro. Essa alteração no comportamento pode causar problemas para aplicativos existentes.

Quando SQLExecute ou SQLExecDirect retorna antes de concluir o processamento de todos os conjuntos de parâmetros em uma matriz de parâmetros, como quando SQL_ERROR ou SQL_NEED_DATA é retornado, a matriz de status contém status para os parâmetros que já foram processados. O local apontado pelo campo SQL_DESC_ROWS_PROCESSED_PTR no IPD contém o número da linha na matriz de parâmetros que causou o código de erro SQL_ERROR ou SQL_NEED_DATA. Quando uma matriz de parâmetros é enviada para uma instrução SELECT, a disponibilidade dos valores da matriz de status é definida pelo driver; eles podem estar disponíveis após a execução da instrução ou à medida que os conjuntos de resultados são buscados.

Ignorando um conjunto de parâmetros

O campo SQL_DESC_ARRAY_STATUS_PTR do APD (conforme definido pelo atributo de instrução SQL_ATTR_PARAM_STATUS_PTR) pode ser usado para indicar que um conjunto de parâmetros associados em uma instrução SQL deve ser ignorado. Para direcionar o driver a ignorar um ou mais conjuntos de parâmetros durante a execução, um aplicativo deve seguir estas etapas:

  1. Chame SQLSetDescField para definir o campo de cabeçalho SQL_DESC_ARRAY_STATUS_PTR do APD para apontar para uma matriz de valores SQLUSMALLINT para conter informações de status. Esse campo também pode ser definido chamando SQLSetStmtAttr com um Atributo de SQL_ATTR_PARAM_OPERATION_PTR, o que permite que um aplicativo defina o campo sem obter um identificador de descritor.

  2. Defina cada elemento da matriz definida pelo campo SQL_DESC_ARRAY_STATUS_PTR do APD como um dos dois valores:

    • SQL_PARAM_IGNORE, para indicar que a linha foi excluída da execução da instrução.

    • SQL_PARAM_PROCEED, para indicar que a linha está incluída na execução da instrução.

  3. Chame SQLExecDirect ou SQLExecute para executar a instrução preparada.

As seguintes regras se aplicam à matriz definida pelo campo SQL_DESC_ARRAY_STATUS_PTR do APD:

  • O ponteiro é definido como nulo por padrão.

  • Se o ponteiro for nulo, todos os conjuntos de parâmetros serão usados, como se todos os elementos tivessem sido definidos como SQL_ROW_PROCEED.

  • Definir um elemento como SQL_PARAM_PROCEED não garante que a operação usará esse conjunto específico de parâmetros.

  • SQL_PARAM_PROCEED é definido como 0 no arquivo de cabeçalho.

Um aplicativo pode definir o campo SQL_DESC_ARRAY_STATUS_PTR no APD para apontar para a mesma matriz apontada pelo campo SQL_DESC_ARRAY_STATUS_PTR no IRD. Isso é útil ao associar parâmetros a dados de linha. Os parâmetros podem ser ignorados de acordo com o status dos dados da linha. Além de SQL_PARAM_IGNORE, os códigos a seguir fazem com que um parâmetro em uma instrução SQL seja ignorado: SQL_ROW_DELETED, SQL_ROW_UPDATED e SQL_ROW_ERROR. Além de SQL_PARAM_PROCEED, os seguintes códigos fazem com que uma instrução SQL prossiga: SQL_ROW_SUCCESS, SQL_ROW_SUCCESS_WITH_INFO e SQL_ROW_ADDED.

Parâmetros de religação

Um aplicativo pode executar uma das duas operações para alterar uma associação:

  • Chame SQLBindParameter para especificar uma nova associação para uma coluna que já está associada. O driver substitui a associação antiga pela nova.

  • Especifique um deslocamento a ser adicionado ao endereço de buffer especificado pela chamada de associação para SQLBindParameter. Para obter mais informações, consulte a próxima seção, "Revinculação com deslocamentos".

Revinculação com deslocamentos

A religação de parâmetros é especialmente útil quando um aplicativo tem uma configuração de área de buffer que pode conter muitos parâmetros, mas uma chamada para SQLExecDirect ou SQLExecute usa apenas alguns dos parâmetros. O espaço restante na área do buffer pode ser usado para o próximo conjunto de parâmetros, modificando a associação existente por um deslocamento.

O campo de cabeçalho SQL_DESC_BIND_OFFSET_PTR no APD aponta para o deslocamento de associação. Se o campo não for nulo, o driver desreferenciará o ponteiro e, se nenhum dos valores nos campos SQL_DESC_DATA_PTR, SQL_DESC_INDICATOR_PTR e SQL_DESC_OCTET_LENGTH_PTR for um ponteiro nulo, adicionará o valor desreferenciado a esses campos nos registros do descritor no tempo de execução. Os novos valores de ponteiro são usados quando as instruções SQL são executadas. O deslocamento permanece válido após a revinculação. Como SQL_DESC_BIND_OFFSET_PTR é um ponteiro para o deslocamento em vez do deslocamento em si, um aplicativo pode alterar o deslocamento diretamente, sem precisar chamar SQLSetDescField ou SQLSetDescRec para alterar o campo do descritor. O ponteiro é definido como nulo por padrão. O campo SQL_DESC_BIND_OFFSET_PTR do ARD pode ser definido por uma chamada para SQLSetDescField ou por uma chamada para SQLSetStmtAttr com um fAttribute de SQL_ATTR_PARAM_BIND_OFFSET_PTR.

O deslocamento de vinculação é sempre adicionado diretamente aos valores nos campos SQL_DESC_DATA_PTR, SQL_DESC_INDICATOR_PTR e SQL_DESC_OCTET_LENGTH_PTR. Se o deslocamento for alterado para um valor diferente, o novo valor ainda será adicionado diretamente ao valor em cada campo do descritor. O novo deslocamento não é adicionado à soma do valor do campo e a quaisquer deslocamentos anteriores.

Descritores

A forma como um parâmetro é vinculado é determinada pelos campos dos APDs e IPDs. Os argumentos em SQLBindParameter são usados para definir esses campos de descritor. Os campos também podem ser definidos pelas funções SQLSetDescField , embora SQLBindParameter seja mais eficiente de usar porque o aplicativo não precisa obter um identificador de descritor para chamar SQLBindParameter.

Cuidado

Chamar SQLBindParameter para uma instrução pode afetar outras instruções. Isso ocorre quando o ARD associado à instrução é explicitamente alocado e também está associado a outras instruções. Como SQLBindParameter modifica os campos do APD, as modificações se aplicam a todas as instruções às quais esse descritor está associado. Se esse não for o comportamento necessário, o aplicativo deverá dissociar esse descritor das outras instruções antes de chamar SQLBindParameter.

Conceitualmente, SQLBindParameter executa as seguintes etapas em sequência:

  1. Chama SQLGetStmtAttr para obter o identificador APD.

  2. Chama SQLGetDescField para obter o campo SQL_DESC_COUNT do APD e, se o valor do argumento ColumnNumber exceder o valor de SQL_DESC_COUNT, chama SQLSetDescField para aumentar o valor de SQL_DESC_COUNT para ColumnNumber.

  3. Chama SQLSetDescField várias vezes para atribuir valores aos seguintes campos do APD:

    • Define SQL_DESC_TYPE e SQL_DESC_CONCISE_TYPE como o valor de ValueType, exceto que, se ValueType for um dos identificadores concisos de um subtipo de data/hora ou intervalo, ele definirá SQL_DESC_TYPE como SQL_DATETIME ou SQL_INTERVAL, respectivamente, definirá SQL_DESC_CONCISE_TYPE como o identificador conciso e definirá SQL_DESC_DATETIME_INTERVAL_CODE como o subcódigo de data/hora ou intervalo correspondente.

    • Define o campo SQL_DESC_OCTET_LENGTH como o valor de BufferLength.

    • Define o campo SQL_DESC_DATA_PTR como o valor de ParameterValue.

    • Define o campo SQL_DESC_OCTET_LENGTH_PTR com o valor de StrLen_or_Ind.

    • Define o campo SQL_DESC_INDICATOR_PTR também com o valor de StrLen_or_Ind.

    O parâmetro StrLen_or_Ind especifica as informações do indicador e o comprimento do valor do parâmetro.

  4. Chama SQLGetStmtAttr para obter o identificador IPD.

  5. Chama SQLGetDescField para obter o campo SQL_DESC_COUNT do IPD e, se o valor do argumento ColumnNumber exceder o valor de SQL_DESC_COUNT, chama SQLSetDescField para aumentar o valor de SQL_DESC_COUNT para ColumnNumber.

  6. Chama SQLSetDescField várias vezes para atribuir valores aos seguintes campos do IPD:

    • Define SQL_DESC_TYPE e SQL_DESC_CONCISE_TYPE como o valor de ParameterType, exceto que, se ParameterType for um dos identificadores concisos de um subtipo de data e hora ou intervalo, ele definirá SQL_DESC_TYPE como SQL_DATETIME ou SQL_INTERVAL, respectivamente, definirá SQL_DESC_CONCISE_TYPE como o identificador conciso e definirá SQL_DESC_DATETIME_INTERVAL_CODE como o subcódigo de data e hora ou intervalo correspondente.

    • Define um ou mais de SQL_DESC_LENGTH, SQL_DESC_PRECISION e SQL_DESC_DATETIME_INTERVAL_PRECISION, conforme apropriado para ParameterType.

    • Define SQL_DESC_SCALE como o valor de DecimalDigits.

Se a chamada para SQLBindParameter falhar, o conteúdo dos campos de descritor que ele teria definido no APD será indefinido e o campo SQL_DESC_COUNT do APD permanecerá inalterado. Além disso, os campos SQL_DESC_LENGTH, SQL_DESC_PRECISION, SQL_DESC_SCALE e SQL_DESC_TYPE do registro apropriado no IPD são indefinidos e o campo SQL_DESC_COUNT do IPD permanece inalterado.

Conversão de chamadas de e para SQLSetParam

Quando um aplicativo ODBC 1.0 chama SQLSetParam em um ODBC 3.x , o driver ODBC 3.x O Gerenciador de Driver mapeia a chamada conforme mostrado na tabela a seguir.

Chamada por aplicativo ODBC 1.0 Chamada para ODBC 3.x motorista
SQLSetParam( StatementHandle, ParameterNumber, ValueType, ParameterType, LengthPrecision, ParameterScale, ParameterValuePtr, StrLen_or_IndPtr); SQLBindParameter( StatementHandle, ParameterNumber, SQL_PARAM_INPUT_OUTPUT, ValueType, ParameterType, ColumnSize, DecimalDigits, ParameterValuePtr, SQL_SETPARAM_VALUE_MAX, StrLen_or_IndPtr);

Exemplos

R. Usar a função SQLBindParameter

No exemplo a seguir, um aplicativo prepara uma instrução SQL para inserir dados na tabela ORDERS. Para cada parâmetro na instrução, o aplicativo chama SQLBindParameter para especificar o tipo de dados ODBC C e o tipo de dados SQL do parâmetro e para associar um buffer a cada parâmetro. Para cada linha de dados, o aplicativo atribui valores de dados a cada parâmetro e chama SQLExecute para executar a instrução.

O exemplo a seguir pressupõe que você tenha uma fonte de dados ODBC em seu computador chamada Northwind associada ao banco de dados Northwind.

Para obter mais exemplos de código, consulte Função SQLBulkOperations, Função SQLProcedures, Função SQLPutData e Função SQLSetPos.

// SQLBindParameter_Function.cpp  
// compile with: ODBC32.lib  
#include <windows.h>  
#include <sqltypes.h>  
#include <sqlext.h>  
  
#define EMPLOYEE_ID_LEN 10  
  
SQLHENV henv = NULL;  
SQLHDBC hdbc = NULL;  
SQLRETURN retcode;  
SQLHSTMT hstmt = NULL;  
SQLSMALLINT sCustID;  
  
SQLCHAR szEmployeeID[EMPLOYEE_ID_LEN];  
SQL_DATE_STRUCT dsOrderDate;  
SQLINTEGER cbCustID = 0, cbOrderDate = 0, cbEmployeeID = SQL_NTS;  
  
int main() {  
   retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);  
   retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0);   
  
   retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);   
   retcode = SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);  
  
   retcode = SQLConnect(hdbc, (SQLCHAR*) "Northwind", SQL_NTS, (SQLCHAR*) NULL, 0, NULL, 0);  
   retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);  
  
   retcode = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, EMPLOYEE_ID_LEN, 0, szEmployeeID, 0, &cbEmployeeID);  
   retcode = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &sCustID, 0, &cbCustID);  
   retcode = SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_TYPE_DATE, SQL_TIMESTAMP, sizeof(dsOrderDate), 0, &dsOrderDate, 0, &cbOrderDate);  
  
   retcode = SQLPrepare(hstmt, (SQLCHAR*)"INSERT INTO Orders(CustomerID, EmployeeID, OrderDate) VALUES (?, ?, ?)", SQL_NTS);  
  
   strcpy_s((char*)szEmployeeID, _countof(szEmployeeID), "BERGS");  
   sCustID = 5;  
   dsOrderDate.year = 2006;  
   dsOrderDate.month = 3;  
   dsOrderDate.day = 17;  
  
   retcode = SQLExecute(hstmt);  
}  

B. Executar um procedimento armazenado usando um parâmetro nomeado

No exemplo a seguir, um aplicativo executa um procedimento armazenado do SQL Server usando um parâmetro nomeado.

// SQLBindParameter_Function_2.cpp  
// compile with: ODBC32.lib  
// sample assumes the following stored procedure:  
// use northwind  
// DROP PROCEDURE SQLBindParameter  
// GO  
//   
// CREATE PROCEDURE SQLBindParameter @quote int  
// AS  
// delete from orders where OrderID >= @quote  
// GO  
#include <windows.h>  
#include <sqltypes.h>  
#include <sqlext.h>  
  
SQLHDESC hIpd = NULL;  
SQLHENV henv = NULL;  
SQLHDBC hdbc = NULL;  
SQLRETURN retcode;  
SQLHSTMT hstmt = NULL;  
SQLCHAR szQuote[50] = "100084";  
SQLINTEGER cbValue = SQL_NTS;  
  
int main() {  
   retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);  
   retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0);   
  
   retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);   
   retcode = SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);  
  
   retcode = SQLConnect(hdbc, (SQLCHAR*) "Northwind", SQL_NTS, (SQLCHAR*) NULL, 0, NULL, 0);  
   retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);  
  
   retcode = SQLPrepare(hstmt, (SQLCHAR*)"{call SQLBindParameter(?)}", SQL_NTS);  
   retcode = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 50, 0, szQuote, 0, &cbValue);  
   retcode = SQLGetStmtAttr(hstmt, SQL_ATTR_IMP_PARAM_DESC, &hIpd, 0, 0);  
   retcode = SQLSetDescField(hIpd, 1, SQL_DESC_NAME, "@quote", SQL_NTS);  
  
   retcode = SQLExecute(hstmt);  
}  
Para obter informações sobre Consulte
Retornando informações sobre um parâmetro em uma instrução Função SQLDescribeParam
Executando uma instrução SQL Função SQLExecDirect
Executando uma instrução SQL preparada Função SQLExecute
Liberando buffers de parâmetro na instrução Função SQLFreeStmt
Retornando o número de parâmetros de instrução Função SQLNumParams
Retornando o próximo parâmetro para o qual enviar dados Função SQLParamData
Especificando vários valores de parâmetro Função SQLParamOptions
Enviando dados de parâmetro em tempo de execução Função SQLPutData

Confira também

Referência de API do ODBC
Arquivos de cabeçalho ODBC
Recuperando parâmetros de saída usando SQLGetData