Escrever aplicativos ODBC 3.x

Quando um aplicativo ODBC 2.x é atualizado para ODBC 3.x, ele deve ser escrito de modo que ele funcione com drivers ODBC 2.x e 3.x. O aplicativo deve incorporar código condicional para aproveitar ao máximo os recursos ODBC 3.x.

O atributo de ambiente SQL_ATTR_ODBC_VERSION deve ser definido como SQL_OV_ODBC2. Isso garantirá que o driver se comporte como um driver ODBC 2.x com relação às alterações descritas na seção Alterações comportamentais.

Se o aplicativo for usar qualquer um dos recursos descritos na seção Novos recursos, o código condicional deverá ser usado para determinar se o driver é um driver ODBC 3.x ou ODBC 2.x. O aplicativo usa SQLGetDiagField e SQLGetDiagRec para obter os SQLSTATEs do ODBC 3.x ao fazer o processamento de erros nesses fragmentos de código condicional. É preciso considerar os seguintes pontos sobre a nova funcionalidade:

  • Um aplicativo afetado pela alteração no comportamento do tamanho do conjunto de linhas deverá ter cuidado para não chamar SQLFetch quando o tamanho da matriz for maior que 1. Esses aplicativos devem substituir chamadas para SQLExtendedFetch por chamadas para SQLSetStmtAttr para definir o atributo de instrução SQL_ATTR_ARRAY_STATUS_PTR e para SQLFetchScroll para que eles tenham código comum que funcione com drivers ODBC 3.x e ODBC 2.x. Como o SQLSetStmtAttr com SQL_ATTR_ROW_ARRAY_SIZE será mapeado para SQLSetStmtAttr com SQL_ROWSET_SIZE para drivers ODBC 2.x, os aplicativos podem simplesmente definir SQL_ATTR_ROW_ARRAY_SIZE para suas operações de busca de várias linhas.

  • A maioria dos aplicativos que estão atualizando não é realmente afetada por alterações nos códigos SQLSTATE. Os aplicativos que são afetados podem fazer uma pesquisa mecânica e substituir na maioria dos casos usando a tabela de conversão de erro na seção "Mapeamento de SQLSTATE" para converter códigos de erro ODBC 3.x em códigos ODBC 2.x. Como o Gerenciador de Driver ODBC 3.x executará o mapeamento de SQLSTATEs ODBC 2.x para SQLSTATEs ODBC 3.x, esses gravadores de aplicativos precisam apenas verificar os SQLSTATEs ODBC 3.x e não se preocupar em incluir SQLSTATEs ODBC 2.x no código condicional.

  • Se um aplicativo fizer grande uso de tipos de dados de data, hora e carimbo de data/hora, ele poderá se declarar um aplicativo ODBC 2.x e usar seu código existente, em vez do código de condição.

A atualização também deve incluir estas etapas:

  • Chame SQLSetEnvAttr antes de alocar uma conexão para definir o atributo de ambiente SQL_ATTR_ODBC_VERSION como SQL_OV_ODBC2.

  • Substitua todas as chamadas para SQLAllocEnv, SQLAllocConnect ou SQLAllocStmt por chamadas para SQLAllocHandle com o argumento HandleType adequado de SQL_HANDLE_ENV, SQL_HANDLE_DBC ou SQL_HANDLE_STMT.

  • Substitua todas as chamadas para SQLFreeEnv ou SQLFreeConnect por chamadas para SQLFreeHandle com o argumento HandleType apropriado de SQL_HANDLE_DBC ou SQL_HANDLE_STMT.

  • Substitua todas as chamadas para SQLSetConnectOption por chamadas para SQLSetConnectAttr. Se você estiver definindo um atributo cujo valor é uma cadeia de caracteres, defina o argumento StringLength de modo adequado. Altere o argumento Attribute de SQL_XXXX para SQL_ATTR_XXXX.

  • Substitua todas as chamadas para SQLGetConnectOption por chamadas para SQLGetConnectAttr. Se você estiver obtendo uma cadeia de caracteres ou atributo binário, defina BufferLength para o valor apropriado e passe um argumento StringLength. Altere o argumento Attribute de SQL_XXXX para SQL_ATTR_XXXX.

  • Substitua todas as chamadas para SQLSetStmtOption por chamadas para SQLSetStmtAttr. Se você estiver definindo um atributo cujo valor é uma cadeia de caracteres, defina o argumento StringLength de modo adequado. Altere o argumento Attribute de SQL_XXXX para SQL_ATTR_XXXX.

  • Substitua todas as chamadas para SQLGetStmtOption por chamadas para SQLGetStmtAttr. Se você estiver obtendo uma cadeia de caracteres ou atributo binário, defina BufferLength para o valor apropriado e passe um argumento StringLength. Altere o argumento Attribute de SQL_XXXX para SQL_ATTR_XXXX.

  • Substituirá todas as chamadas para SQLTransact por chamadas para SQLEndTran. Se o identificador válido mais à direita na chamada SQLTransact for um identificador de ambiente, um argumento HandleType de SQL_HANDLE_ENV deverá ser usado na chamada SQLEndTran com o argumento Handle apropriado. Se o identificador válido mais à direita na chamada SQLTransact for um identificador de conexão, um argumento HandleType de SQL_HANDLE_DBC deverá ser usado na chamada SQLEndTran com o argumento Handle apropriado.

  • Substitua todas as chamadas para SQLColAttributes por chamadas para SQLColAttribute. Se o argumento FieldIdentifier for SQL_COLUMN_PRECISION, SQL_COLUMN_SCALE ou SQL_COLUMN_LENGTH, não altere nada além do nome da função. Caso contrário, altere FieldIdentifier de SQL_COLUMN_XXXX para SQL_DESC_XXXX. Se FieldIdentifier for SQL_DESC_CONCISE_TYPE e o tipo de dados for um tipo de dados datetime, altere para o tipo de dados ODBC 3.x correspondente.

  • Se estiver usando cursores em bloco, cursores roláveis ou ambos, o aplicativo fará o seguinte:

    • Definirá o tamanho do conjunto de linhas, o tipo de cursor e a simultaneidade do cursor usando SQLSetStmtAttr.

    • Chamara SQLSetStmtAttr para definir SQL_ATTR_ROW_STATUS_PTR para apontar para uma matriz de registros de status.

    • Chamará SQLSetStmtAttr para definir SQL_ATTR_ROWS_FETCHED_PTR para apontar para um SQLINTEGER.

    • Executará as associações necessárias e executa a instrução SQL.

    • Chamará SQLFetchScroll em um loop para efetuar fetch de linhas e mover-se no conjunto de resultados.

    • Se quiser efetuar fetch por indicador, o aplicativo chamará SQLSetStmtAttr para definir SQL_ATTR_FETCH_BOOKMARK_PTR para uma variável que conterá o indicador da linha que ele deseja buscar e chamará SQLFetchScroll com um argumento FetchOrientation de SQL_FETCH_BOOKMARK.

  • Caso esteja usando matrizes de parâmetros, o aplicativo fará o seguinte:

    • Chamará SQLSetStmtAttr para definir o atributo SQL_ATTR_PARAMSET_SIZE para o tamanho da matriz de parâmetros.

    • Chamará SQLSetStmtAttr para definir SQL_ATTR_ROWS_PROCESSED_PTR para apontar para uma variável UDWORD interna.

    • Executará operações de preparação, vinculação e execução conforme apropriado.

    • Se a execução for interrompida por algum motivo (como SQL_NEED_DATA), ele poderá encontrar a linha "atual" de parâmetros inspecionando o local apontado por SQL_ATTR_ROWS_PROCESSED_PTR.

Esta seção contém os tópicos a seguir.