Mapear funções de substituição para compatibilidade com versões anteriores de aplicativos

Um aplicativo ODBC 3.x que funciona por meio do Gerenciador de Driver ODBC 3.x funcionará em um driver ODBC 2.x, desde que nenhum novo recurso seja usado. No entanto, a funcionalidade duplicada e as alterações de comportamento afetam a maneira como o aplicativo ODBC 3.x funciona em um driver ODBC 2.x. Ao trabalhar com um driver ODBC 2.x, o Gerenciador de Driver mapeia as seguintes funções ODBC 3.x, que substituíram uma ou mais funções ODBC 2.x, para as funções ODBC 2.x correspondentes.

Função ODBC 3.x Função ODBC 2.x
SQLAllocHandle SQLAllocEnv, SQLAllocConnect ou SQLAllocStmt
SQLBulkOperations SQLSetPos
SQLColAttribute SQLColAttributes
SQLEndTran SQLTransact
SQLFetch SQLExtendedFetch
SQLFetchScroll SQLExtendedFetch
SQLFreeHandle SQLFreeEnv, SQLFreeConnect ou SQLFreeStmt
SQLGetConnectAttr SQLGetConnectOption
SQLGetDiagRec SQLError
SQLGetStmtAttr SQLGetStmtOption[1]
SQLSetConnectAttr SQLSetConnectOption
SQLSetStmtAttr SQLSetStmtOption[1]

[1] Outras ações também podem ser tomadas, dependendo do atributo que está sendo solicitado.

SQLAllocHandle

O Gerenciador de Driver mapeia isso para SQLAllocEnv, SQLAllocConnect ou SQLAllocStmt, conforme apropriado. A seguinte chamada para SQLAllocHandle:

SQLAllocHandle(HandleType, InputHandle, OutputHandlePtr);  

resultará no Gerenciador de Driver executando o seguinte mapeamento (conceitual, sem verificação de erros):

switch (HandleType) {  
   case SQL_HANDLE_ENV: return (SQLAllocEnv(OutputHandlePtr));  
   case SQL_HANDLE_DBC: return (SQLAllocConnect (InputHandle, OutputHandlePtr));  
   case SQL_HANDLE_STMT: return (SQLAllocStmt (InputHandle, OutputHandlePtr));  
   default: // return SQL_ERROR, SQLSTATE HY092 ("Invalid attribute/option identifier")  
}  

SQLBulkOperations

O Gerenciador de Driver mapeia isso para SQLSetPos. A seguinte chamada para SQLBulkOperations:

SQLBulkOperations(hstmt, Operation);  

resultará na seguinte sequência de etapas:

  1. Se o argumento de operação for SQL_ADD, o Gerenciador de Driver chamará SQLSetPos da seguinte maneira:

    SQLSetPos (hstmt, 0, SQL_ADD, SQL_LOCK_NO_CHANGE);  
    
  2. Se o argumento de operação não for SQL_ADD, o driver retornará SQLSTATE HY092 (identificador de opção/atributo inválido).

  3. Se o aplicativo tentar alterar o SQL_ATTR_ROW_STATUS_PTR entre chamadas para SQLFetch ou SQLFetchScroll e SQLBulkOperations, o Gerenciador de Driver retornará SQLSTATE HY011 (o atributo não pode ser definido agora).

  4. Se o argumento de operação for SQL_ADD, o aplicativo deverá chamar SQLBindCol para associar os dados a serem inseridos. Ele não pode chamar SQLSetDescField ou SQLSetDescRec para associar os dados a serem inseridos.

  5. Se o argumento de operação for SQL_ADD e o número de linhas a serem inseridas não for o mesmo que o tamanho atual do conjunto de linhas, SQLSetStmtAttr deverá ser chamado para definir o atributo de instrução SQL_ATTR_ROW_ARRAY_SIZE para o número de linhas a serem inseridas antes de chamar SQLBulkOperations. Para reverter para o tamanho do conjunto de linhas anterior, o aplicativo deve definir o atributo de instrução SQL_ATTR_ROW_ARRAY_SIZE antes que SQLFetch, SQLFetchScroll ou SQLSetPos seja chamado.

SQLColAttribute

O Gerenciador de Driver mapeia isso para SQLColAttributes. A seguinte chamada para SQLColAttribute:

SQLColAttribute(StatementHandle, ColumnNumber, FieldIdentifier, CharacterAttributePtr, BufferLength, StringLengthPtr, NumericAttributePtr);  

resultará na seguinte sequência de etapas:

  1. Se FieldIdentifier for um dos seguintes:

    SQL_DESC_PRECISION, SQL_DESC_SCALE, SQL_DESC_LENGTH, SQL_DESC_OCTET_LENGTH, SQL_DESC_UNNAMED, SQL_DESC_BASE_COLUMN_NAME, SQL_DESC_LITERAL_PREFIX, SQL_DESC_LITERAL_SUFFIX ou SQL_DESC_LOCAL_TYPE_NAME

    o Gerenciador de Driver retorna SQL_ERROR com SQLSTATE HY091 (identificador de campo descritor inválido). Nenhuma outra regra desta seção se aplica.

  2. O Gerenciador de Driver mapeia SQL_COLUMN_COUNT, SQL_COLUMN_NAME ou SQL_COLUMN_NULLABLE para SQL_DESC_COUNT, SQL_DESC_NAME ou SQL_DESC_NULLABLE, respectivamente. (Um driver ODBC 2.x só precisa oferecer suporte a SQL_COLUMN_COUNT, SQL_COLUMN_NAME e SQL_COLUMN_NULLABLE, não SQL_DESC_COUNT, SQL_DESC_NAME e SQL_DESC_NULLABLE.) A chamada para SQLColAttribute é mapeada para:

    SQLColAttributes(StatementHandle, ColumnNumber, FieldIdentifier, CharacterAttributePtr, BufferLength, StringLengthPtr, NumericAttributePtr);  
    
  3. Todos os outros valores FieldIdentifier são passados para o driver, com SQLColAttribute mapeado para SQLColAttributes como mostrado anteriormente.

  4. Se BufferLength for menor que 0, o Gerenciador de Driver retornará SQL_ERROR com SQLSTATE HY090 (cadeia de caracteres inválida ou comprimento do buffer). Nenhuma outra regra desta seção se aplica.

  5. Se FieldIdentifier for SQL_DESC_CONCISE_TYPE e o tipo retornado for um tipo de dados datetime conciso, o Gerenciador de Driver mapeia os valores de retorno para códigos de data, hora e carimbo de data/hora.

  6. O Gerenciador de Driver executa as verificações necessárias para ver se SQLSTATE HY010 (erro de sequência de função) precisa ser gerado. Nesse caso, o Gerenciador de Driver retorna SQL_ERROR e SQLSTATE HY010 (erro de sequência de função). Nenhuma outra regra desta seção se aplica.

SQLEndTran

O Gerenciador de Driver mapeia isso para SQLTransact. A seguinte chamada para SQLEndTran:

SQLEndTran(HandleType, Handle, CompletionType);  

resultará no Gerenciador de Driver executando o seguinte mapeamento (conceitual, sem verificação de erros):

switch (HandleType) {  
   case SQL_HANDLE_ENV:return(SQLTransact(Handle, SQL_NULL_HDBC, CompletionType));  
   case SQL_HANDLE_DBC:return(SQLTransact(SQL_NULL_HENV, Handle, CompletionType);  
   default: // return SQL_ERROR, SQLSTATE HY092 ("Invalid attribute/option identifier")  
}  

SQLFetch

O Gerenciador de Driver mapeia isso para SQLExtendedFetch com um argumento FetchOrientation de SQL_FETCH_NEXT. A seguinte chamada para SQLFetch:

SQLFetch (StatementHandle);  

resultará no Gerenciador de Driver chamando SQLExtendedFetch da seguinte maneira:

rc = SQLExtendedFetch(StatementHandle, FetchOrientation, FetchOffset, &RowCount, RowStatusArray);  

Nessa chamada, o argumento pcRow é definido como o valor para o qual o aplicativo define o atributo de instrução SQL_ATTR_ROWS_FETCHED_PTR por meio de uma chamada para SQLSetStmtAttr.

Observação

Quando o aplicativo chama SQLSetStmtAttr para definir SQL_ATTR_ROW_STATUS_PTR para apontar para uma matriz de status, o Gerenciador de Driver armazena o ponteiro em cache. RowStatusArray pode ser igual a um ponteiro nulo.

Se o driver não oferecer suporte a SQLExtendedFetch e a biblioteca de cursores for carregada, o Gerenciador de Driver usará SQLExtendedFetch da biblioteca de cursores para mapear SQLFetch para SQLExtendedFetch. Se o driver não oferecer suporte a SQLExtendedFetch e a biblioteca de cursores não estiver carregada, o Gerenciador de Driver passará a chamada para SQLFetch para o driver. Se o aplicativo chamar SQLSetStmtAttr para definir SQL_ATTR_ROW_STATUS_PTR, o Gerenciador de Driver garantirá que a matriz seja preenchida. Se o aplicativo chamar SQLSetStmtAttr para definir SQL_ATTR_ROWS_FETCHED_PTR, o Gerenciador de Driver definirá esse campo como 1.

SQLFetchScroll

O Gerenciador de Driver mapeia isso para SQLExtendedFetch. A seguinte chamada para SQLFetchScroll:

SQLFetchScroll(StatementHandle, FetchOrientation, FetchOffset);  

resultará na seguinte sequência de etapas:

  1. Quando o aplicativo chama SQLSetStmtAttr para definir SQL_ATTR_ROW_STATUS_PTR (que define o campo SQL_DESC_ARRAY_STATUS_PTR no IRD) para apontar para uma matriz de status, o Gerenciador de Driver armazena esse ponteiro em cache. Deixe esse ponteiro ser RowStatusArray, caso contrário, deixe RowStatusArray ser igual a um ponteiro nulo. Se o argumento RowStatusArray estiver definido como um ponteiro nulo, o Gerenciador de Driver gerará uma matriz de status de linha.

  2. Se FetchOrientation não for SQL_FETCH_NEXT, SQL_FETCH_PRIOR, SQL_FETCH_ABSOLUTE, SQL_FETCH_RELATIVE, SQL_FETCH_FIRST, SQL_FETCH_LAST ou SQL_FETCH_BOOKMARK, o Gerenciador de Driver retornará com SQL_ERROR e SQLSTATE HY106 (tipo de busca fora do intervalo). Nenhuma outra regra desta seção se aplica.

  3. Capitalização:

  • Se FetchOrientation for igual a SQL_FETCH_BOOKMARK, então:

    • Se SQLSetStmtAttr foi chamado anteriormente para definir o valor de SQL_ATTR_FETCH_BOOKMARK_PTR, então deixe Bmk ser o valor obtido ao desreferenciar o ponteiro SQL_DESC_FETCH_BOOKMARK_PTR.

    • Caso contrário, retorne SQL_ERROR com SQLSTATE HY111 (valor de indicador inválido). Nenhuma outra regra desta seção se aplica.

    O Gerenciador de Driver agora chama SQLExtendedFetch da seguinte maneira:

    rc = SQLExtendedFetch(StatementHandle, FetchOrientation, Bmk, pcRow, RowStatusArray);  
    
  • Caso contrário, o Gerenciador de Driver chama SQLExtendedFetch da seguinte maneira:

    rc = SQLExtendedFetch(StatementHandle, FetchOrientation, FetchOffset, pcRow, RowStatusArray);  
    

    Nessas chamadas, o argumento pcRow é definido como o valor para o qual o aplicativo define o atributo de instrução SQL_ATTR_ROWS_FETCHED_PTR por meio de uma chamada para SQLSetStmtAttr.

  • SQL_ATTR_ROW_ARRAY_SIZE é mapeado para SQL_ROWSET_SIZE.

  • Se rc for igual a SQL_SUCCESS ou SQL_SUCCESS_WITH_INFO, e se FetchOrientation for igual a SQL_FETCH_BOOKMARK e FetchOffset não for igual a 0, o Gerenciador de Driver publicará um aviso, SQLSTATE 01S10 (tentativa de buscar por um deslocamento de indicador, valor de deslocamento ignorado) e retornará SQL_SUCCESS_WITH_INFO.

SQLFreeHandle

O Gerenciador de Driver mapeia isso para SQLFreeEnv, SQLFreeConnect ou SQLFreeStmt, conforme apropriado. A seguinte chamada para SQLFreeHandle:

SQLFreeHandle(HandleType, Handle);  

resultará no Gerenciador de Driver executando o seguinte mapeamento (conceitual, sem verificação de erros):

switch (HandleType) {  
   case SQL_HANDLE_ENV: return (SQLFreeEnv(Handle));  
   case SQL_HANDLE_DBC: return (SQLFreeConnect(Handle));  
   case SQL_HANDLE_STMT: return (SQLFreeStmt(Handle, SQL_DROP));  
   default: // return SQL_ERROR, SQLSTATE HY092 ("Invalid attribute/option identifier")  
}  

SQLGetConnectAttr

O Gerenciador de Driver mapeia isso para SQLGetConnectOption. A seguinte chamada para SQLGetConnectAttr:

SQLGetConnectAttr(ConnectionHandle, Attribute, ValuePtr, BufferLength, StringLengthPtr);  

resultará na seguinte sequência de etapas:

  1. Se Attribute não for um atributo de conexão ou instrução definido pelo driver e não for um atributo definido no ODBC 2.x, o Gerenciador de Driver retornará SQL_ERROR com SQLSTATE HY092 (identificador de opção/atributo inválido). Nenhuma outra regra nesta seção se aplica.

  2. Se Attribute for igual a SQL_ATTR_AUTO_IPD ou SQL_ATTR_METADATA_ID, o Gerenciador de Driver retornará SQL_ERROR com SQLSTATE HY092 (identificador de opção/atributo inválido).

  3. O Gerenciador de Driver executa as verificações necessárias para ver se SQLSTATE 08003 (conexão não aberta) ou SQLSTATE HY010 (erro de sequência de função) precisa ser gerado. Nesse caso, o Gerenciador de Driver retorna SQL_ERROR e posta a mensagem de erro apropriada. Nenhuma outra regra desta seção se aplica.

  4. O Gerenciador de Driver chama SQLGetConnectOption da seguinte maneira:

    SQLGetConnectOption (ConnectionHandle, Attribute, ValuePtr);  
    

    Observe que BufferLength e StringLengthPtr são ignorados.

SQLGetData

Quando um aplicativo ODBC 3.x trabalhando com um driver ODBC 2.x chama SQLGetData com o argumento ColumnNumber igual a 0, o Gerenciador de Driver ODBC 3.x mapeia isso para uma chamada para SQLGetStmtOption com o atributo Option definido como SQL_GET_BOOKMARK.

SQLGetStmtAttr

O Gerenciador de Driver mapeia isso para SQLGetStmtOption. A seguinte chamada para SQLGetStmtAttr:

SQLGetStmtAttr(StatementHandle, Attribute, ValuePtr, BufferLength, StringLengthPtr);  

resultará na seguinte sequência de etapas:

  1. Se Attribute não for um atributo de conexão ou instrução definido pelo driver e não for um atributo definido no ODBC 2.x, o Gerenciador de Driver retornará SQL_ERROR com SQLSTATE HY092 (identificador de opção/atributo inválido). Nenhuma outra regra nesta seção se aplica.

  2. Se Attribute for um dos seguintes:

    SQL_ATTR_APP_ROW_DESC

    SQL_ATTR_APP_PARAM_DESC

    SQL_ATTR_AUTO_IPD

    SQL_ATTR_ROW_BIND_TYPE

    SQL_ATTR_IMP_ROW_DESC

    SQL_ATTR_IMP_PARAM_DESC

    SQL_ATTR_METADATA_ID

    SQL_ATTR_PARAM_BIND_TYPE

    SQL_ATTR_PREDICATE_PTR

    SQL_ATTR_PREDICATE_OCTET_LENGTH_PTR

    SQL_ATTR_PARAM_BIND_OFFSET_PTR

    SQL_ATTR_ROW_BIND_OFFSET_PTR

    SQL_ATTR_ROW_OPERATION_PTR

    SQL_ATTR_PARAM_OPERATION_PTR

    o Gerenciador de Driver retorna SQL_ERROR com SQLSTATE HY092 (identificador de opção/atributo inválido). Nenhuma outra regra desta seção se aplica.

  3. O Gerenciador de Driver executa as verificações necessárias para ver se SQLSTATE HY010 (erro de sequência de função) precisa ser gerado. Nesse caso, o Gerenciador de Driver retorna SQL_ERROR e SQLSTATE HY010 (erro de sequência de função). Nenhuma outra regra desta seção se aplica.

  4. Se Attribute for igual a SQL_ATTR_ROWS_FETCHED_PTR, o Gerenciador de Driver retornará um ponteiro para a variável interna do Gerenciador de Driver cRow, que ele usou ou usará em uma chamada para SQLExtendedFetch. Nenhuma outra regra desta seção se aplica.

  5. Se Attribute for igual a SQL_DESC_FETCH_BOOKMARK_PTR, o Gerenciador de Driver retornará o ponteiro apropriado que ele armazenou em cache durante uma chamada para SQLSetStmtAttr.

  6. Se Attribute for igual a SQL_ATTR_ROW_STATUS_PTR, o Gerenciador de Driver retornará o ponteiro apropriado que ele armazenou em cache durante uma chamada para SQLSetStmtAttr.

  7. O Gerenciador de Driver chama SQLGetStmtOption da seguinte maneira:

    SQLGetStmtOption (hstmt, fOption, pvParam);  
    

    em que hstmt, fOption e pvParam serão definidos como os valores de StatementHandle, Attribute e ValuePtr, respectivamente. BufferLength e StringLengthPtr são ignorados.

SQLSetConnectAttr

O Gerenciador de Driver mapeia isso para SQLSetConnectOption. A seguinte chamada para SQLSetConnectAttr:

SQLSetConnectAttr(ConnectionHandle, Attribute, ValuePtr, StringLength);  

resultará na seguinte sequência de etapas:

  1. Se Attribute não for um atributo de conexão ou instrução definido pelo driver e não for um atributo definido no ODBC 2.x, o Gerenciador de Driver retornará SQL_ERROR com SQLSTATE HY092 (identificador de opção/atributo inválido). Nenhuma outra regra nesta seção se aplica.

  2. Se Attribute for igual a SQL_ATTR_AUTO_IPD, o Gerenciador de Driver retornará SQL_ERROR com SQLSTATE HY092 (identificador de opção/atributo inválido).

  3. O Gerenciador de Driver executa as verificações necessárias para ver se SQLSTATE 08003 (conexão não aberta) ou SQLSTATE HY010 (erro de sequência de função) precisa ser gerado. Se um desses erros precisar ser gerado, o Gerenciador de Driver retornará SQL_ERROR e postará a mensagem de erro apropriada. Nenhuma outra regra desta seção se aplica.

  4. O Gerenciador de Driver chama SQLSetConnectOption da seguinte maneira:

    SQLSetConnectOption (hdbc, fOption, vParam);  
    

    em que hdbc, fOption e vParam serão definidos como os valores de ConnectionHandle, Attribute e ValuePtr, respectivamente. StringLengthPtr é ignorado.

Observação

A capacidade de definir atributos de instrução no nível de conexão foi preterida. Os atributos de instrução nunca devem ser definidos no nível de conexão por um aplicativo ODBC 3.x .

SQLSetStmtAttr

O Gerenciador de Driver mapeia isso para SQLSetStmtOption. A seguinte chamada para SQLSetStmtAttr:

SQLSetStmtAttr(StatementHandle, Attribute, ValuePtr, StringLength);  

resultará na seguinte sequência de etapas:

  1. Se Attribute não for um atributo de conexão ou instrução definido pelo driver e não for um atributo definido no ODBC 2.x, o Gerenciador de Driver retornará SQL_ERROR com SQLSTATE HY092 (identificador de opção/atributo inválido). Nenhuma outra regra nesta seção se aplica.

  2. Se Attribute for um dos seguintes:

    SQL_ATTR_APP_ROW_DESC

    SQL_ATTR_APP_PARAM_DESC

    SQL_ATTR_AUTO_IPD

    SQL_ATTR_ROW_BIND_TYPE

    SQL_ATTR_IMP_ROW_DESC

    SQL_ATTR_IMP_PARAM_DESC

    SQL_ATTR_METADATA_ID

    SQL_ATTR_PARAM_BIND_TYPE

    SQL_ATTR_PREDICATE_PTR

    SQL_ATTR_PREDICATE_OCTET_LENGTH_PTR

    SQL_ATTR_PARAM_BIND_OFFSET_PTR

    SQL_ATTR_ROW_BIND_OFFSET_PTR

    SQL_ATTR_ROW_OPERATION_PTR

    SQL_ATTR_PARAM_OPERATION_PTR

    o Gerenciador de Driver retorna SQL_ERROR com SQLSTATE HY092 (identificador de opção/atributo inválido). Nenhuma outra regra desta seção se aplica.

  3. O Gerenciador de Driver executa as verificações necessárias para ver se SQLSTATE HY010 (erro de sequência de função) precisa ser gerado. Nesse caso, o Gerenciador de Driver retorna SQL_ERROR e SQLSTATE HY010 (erro de sequência de função). Nenhuma outra regra desta seção se aplica.

  4. Se Attribute for igual a SQL_ATTR_PARAMSET_SIZE ou SQL_ATTR_PARAMS_PROCESSED_PTR, confira a seção "Mapeamentos para manipulação de matrizes de parâmetros", mais adiante neste tópico. Nenhuma outra regra desta seção se aplica.

  5. Se Attribute for igual a SQL_ATTR_ROWS_FETCHED_PTR, o Gerenciador de Driver armazenará em cache o valor do ponteiro para uso posterior com SQLFetchScroll.

  6. Se Attribute for igual a SQL_ATTR_ROW_STATUS_PTR, o Gerenciador de Driver armazenará em cache o valor do ponteiro para uso posterior com SQLFetchScroll ou SQLSetPos. Nenhuma outra regra desta seção se aplica.

  7. Se Attribute for igual a SQL_ATTR_FETCH_BOOKMARK_PTR, o Gerenciador de Driver armazenará ValuePtr em cache e usará o valor armazenado em cache posteriormente em uma chamada para SQLFetchScroll. Nenhuma outra regra desta seção se aplica.

  8. O Gerenciador de Driver chama SQLSetStmtOption da seguinte maneira:

    SQLSetStmtOption (hstmt, fOption, vParam);  
    

    em que hstmt, fOption e vParam serão definidos como os valores de StatementHandle, Attribute e ValuePtr, respectivamente. O argumento StringLength é ignorado.

    Se um driver ODBC 2.x oferecer suporte a opções de instrução específicas de driver e cadeia de caracteres, um aplicativo ODBC 3.x deverá chamar SQLSetStmtOption para definir essas opções.

Mapeamentos para manipulação de matrizes de parâmetros

Quando o aplicativo chama:

SQLSetStmtAttr (StatementHandle, SQL_ATTR_PARAMSET_SIZE, Size, StringLength);  

o Gerenciador de Driver chama:

SQLParamOptions (StatementHandle, Size, &RowCount);  

O Gerenciador de Driver posteriormente retorna um ponteiro para essa variável quando o aplicativo chama SQLGetStmtAttr para recuperar SQL_ATTR_PARAMS_PROCESSED_PTR. O Gerenciador de Driver não pode alterar essa variável interna até que o identificador de instrução seja retornado ao estado preparado ou atribuído.

Um aplicativo ODBC 3.x pode chamar SQLGetStmtAttr para obter o valor de SQL_ATTR_PARAMS_PROCESSED_PTR mesmo que ele não tenha definido explicitamente o campo SQL_DESC_ARRAY_SIZE no APD. Essa situação pode ocorrer, por exemplo, se o aplicativo tiver uma rotina genérica que verifique a "linha" atual de parâmetros que estão sendo processados quando SQLExecute retorna SQL_NEED_DATA. Essa rotina é invocada independentemente de o SQL_DESC_ARRAY_SIZE ser 1 ou maior que 1. Para explicar isso, o Gerenciador de Driver precisará definir essa variável interna se o aplicativo chamou ou não SQLSetStmtAttr para definir o campo SQL_DESC_ARRAY_SIZE no APD. Se SQL_DESC_ARRAY_SIZE não tiver sido definido, o Gerenciador de Driver deverá se certificar de que essa variável contenha o valor 1 antes de retornar de SQLExecDirect ou SQLExecute.

Manipulação de Erro

No ODBC 3.x, chamar SQLFetch ou SQLFetchScroll preenche o SQL_DESC_ARRAY_STATUS_PTR no IRD, e o campo SQL_DIAG_ROW_NUMBER de um determinado registro de diagnóstico contém o número da linha no conjunto de linhas ao qual esse registro pertence. Usando isso, o aplicativo pode correlacionar uma mensagem de erro com uma determinada posição de linha.

Um driver ODBC 2.x não poderá fornecer essa funcionalidade. No entanto, ele fornecerá demarcação de erro com SQLSTATE 01S01 (erro na linha). Um aplicativo ODBC 3.x que está usando SQLFetch ou SQLFetchScroll ao ir contra um driver ODBC 2.x precisa estar ciente desse fato. Observe também que esse aplicativo não poderá chamar SQLGetDiagField para realmente obter o campo SQL_DIAG_ROW_NUMBER de qualquer forma. Um aplicativo ODBC 3.x trabalhando com um driver ODBC 2.x poderá chamar SQLGetDiagField somente com um argumento DiagIdentifier de SQL_DIAG_MESSAGE_TEXT, SQL_DIAG_NATIVE, SQL_DIAG_RETURNCODE ou SQL_DIAG_SQLSTATE. O Gerenciador de Driver ODBC 3.x mantém a estrutura de dados de diagnóstico ao trabalhar com um driver ODBC 2.x, mas o driver ODBC 2.x retorna apenas esses quatro campos.

Quando um aplicativo ODBC 2.x está trabalhando com um driver ODBC 2.x, se uma operação pode causar vários erros a serem retornados pelo Gerenciador de Driver, erros diferentes podem ser retornados pelo Gerenciador de Driver ODBC 3.x do que pelo Gerenciador de Driver ODBC 2.x.

Mapeamentos para operações de indicador

O Gerenciador de Driver ODBC 3.x executa os seguintes mapeamentos quando um aplicativo ODBC 3.x que trabalha com um driver ODBC 2.x executa operações de indicador.

SQLBindCol

Quando um aplicativo ODBC 3.x trabalhando com um driver ODBC 2.x chama SQLBindCol para associar à coluna 0 com fCType igual a SQL_C_VARBOOKMARK, o Gerenciador de Driver ODBC 3.x verifica se o argumento BufferLength é menor que 4 ou maior que 4 e, em caso afirmativo, retorna SQLSTATE HY090 (cadeia de caracteres inválida ou comprimento do buffer). Se o argumento BufferLength for igual a 4, o Gerenciador de Driver chamará SQLBindCol no driver, depois de substituir fCType por SQL_C_BOOKMARK.

SQLColAttribute

Quando um aplicativo ODBC 3.x trabalhando com um driver ODBC 2.x chama SQLColAttribute com o argumento ColumnNumber definido como 0, o Gerenciador de Driver retorna os valores FieldIdentifier listados na tabela a seguir.

FieldIdentifier Valor
SQL_DESC_AUTO_UNIQUE_VALUE SQL_FALSE
SQL_DESC_CASE_SENSITIVE SQL_FALSE
SQL_DESC_CATALOG_NAME "" (cadeia de caracteres vazia)
SQL_DESC_CONCISE_TYPE SQL_BINARY
SQL_DESC_COUNT O mesmo valor retornado por SQLNumResultCols
SQL_DESC_DATETIME_INTERVAL_CODE 0
SQL_DESC_DISPLAY_SIZE 8
SQL_DESC_FIXED_PREC_SCALE SQL_FALSE
SQL_DESC_LABEL "" (cadeia de caracteres vazia)
SQL_DESC_LENGTH 0
SQL_DESC_LITERAL_PREFIX "" (cadeia de caracteres vazia)
SQL_DESC_LITERAL_SUFFIX "" (cadeia de caracteres vazia)
SQL_DESC_LOCAL_TYPE_NAME "" (cadeia de caracteres vazia)
SQL_DESC_NAME "" (cadeia de caracteres vazia)
SQL_DESC_NULLABLE SQL_NO_NULLS
SQL_DESC_OCTET_LENGTH 4
SQL_DESC_PRECISION 4
SQL_DESC_SCALE 0
SQL_DESC_SCHEMA_NAME "" (cadeia de caracteres vazia)
SQL_DESC_SEARCHABLE SQL_PRED_NONE
SQL_DESC_TABLE_NAME "" (cadeia de caracteres vazia)
SQL_DESC_TYPE SQL_BINARY
SQL_DESC_TYPE_NAME "" (cadeia de caracteres vazia)
SQL_DESC_UNNAMED SQL_UNNAMED
SQL_DESC_UNSIGNED SQL_FALSE
SQL_DESC_UPDATEABLE SQL_ATTR_READ_ONLY

SQLDescribeCol

Quando um aplicativo ODBC 3.x trabalhando com um driver ODBC 2.x chama SQLDescribeCol com o argumento ColumnNumber definido como 0, o Gerenciador de Driver retorna os valores listados na tabela a seguir.

Buffer Valor
ColumnName "" (cadeia de caracteres vazia)
*NameLengthPtr 0
*DataTypePtr SQL_BINARY
*ColumnSizePtr 4
*DecimalDigitsPtr 0
*NullablePtr SQL_NO_NULLS

SQLGetData

Quando um aplicativo ODBC 3.x trabalhando com um driver ODBC 2.x faz a seguinte chamada para SQLGetData para recuperar um indicador:

SQLGetData(StatementHandle, 0, SQL_C_VARBOOKMARK, TargetValuePtr, BufferLength, StrLen_or_IndPtr)  

a chamada é mapeada para SQLGetStmtOption com um fOption de SQL_GET_BOOKMARK, da seguinte maneira:

SQLGetStmtOption(hstmt, SQL_GET_BOOKMARK, TargetValuePtr)  

em que hstmt e pvParam são definidos como os valores em StatementHandle e TargetValuePtr, respectivamente. O indicador é retornado no buffer apontado pelo argumento pvParam (TargetValuePtr). O valor no buffer apontado pelo argumento StrLen_or_IndPtr na chamada para SQLGetData é definido como 4.

Esse mapeamento é necessário para levar em conta o caso em que SQLFetch foi chamado antes da chamada para SQLGetData e o driver ODBC 2.x não deu suporte a SQLExtendedFetch. Nesse caso, o SQLFetch seria passado para o driver ODBC 2.x, em que a recuperação de indicadores não é suportada.

SQLGetData não pode ser chamado várias vezes em um driver ODBC 2.x para recuperar um indicador em partes, portanto, chamar SQLGetData com o argumento BufferLength definido como um valor menor que 4 e o argumento ColumnNumber definido como 0 retornará SQLSTATE HY090 (cadeia de caracteres inválida ou comprimento do buffer). SQLGetData pode, no entanto, ser chamado várias vezes para recuperar o mesmo indicador.

SQLSetStmtAttr

Quando um aplicativo ODBC 3.x trabalhando com um driver ODBC 2.x chama SQLSetStmtAttr para definir o atributo SQL_ATTR_USE_BOOKMARKS como SQL_UB_VARIABLE, o Gerenciador de Driver define o atributo como SQL_UB_ON no driver ODBC 2.x subjacente.