Síntomas
Cuando se intenta establecer un atributo de conexión de una conexión ODBC donde está habilitada la agrupación de conexiones utilizando la API de controlador ODBC con el controlador ODBC de Microsoft SQL Server, recibirá el siguiente mensaje de error:
IM006 SQLSetConnectAttr del controlador [Microsoft] [Administrador de controladores ODBC] no se pudo
Nota: La documentación del controlador ODBC se menciona que el mensaje es un mensaje informativo. Sin embargo, recibirá el mensaje como un mensaje de error.
Este problema puede producirse cuando se cumplen todas las condiciones siguientes:-
Realizar la conexión con un nombre de origen de datos (DSN) utilizando la API de controlador ODBC SQLConnect.
-
Una de las propiedades predeterminadas del DSN (por ejemplo, la opción de los valores nulos, rellenos y advertencias ANSI de uso ) está deshabilitada.
-
Agrupación de conexiones está habilitada para el identificador de entorno.
-
El atributo de nivel de aislamiento de la conexión se establece después de abrir la conexión utilizando SQLConnect.
-
Se realiza una transacción de base de datos.
Solución alternativa
Para evitar este problema, siga estos pasos:
-
Deshabilitar la opción para la conexión ODBC agrupación de conexiones.
Nota: Deshabilitar la agrupación de conexiones puede afectar al rendimiento de la aplicación. -
Después de confirmar la transacción, no active la opción de confirmación automática.
-
Establezca el nivel de aislamiento de transacción antes de abrir la conexión ODBC.
-
Utilizar una conexión sin DSN en lugar de obtener la conexión ODBC con DSN.
Solución
Existe un hotfix disponible desde Microsoft. Sin embargo, esta revisión se diseñó para corregir únicamente el problema que se describe en este artículo. Aplíquela sólo a sistemas que experimenten este problema específico.
Si la revisión está disponible para su descarga, hay una sección de "Descarga de revisión disponible" en la parte superior de este artículo de Knowledge Base. Si esta sección no aparece, envíe una solicitud al servicio de atención al cliente y soporte técnico para obtener la revisión. Nota: Si se producen problemas adicionales o si se requiere cualquier otra solución, será necesario crear una solicitud de revisión independiente. Los costos habituales de soporte se aplicarán a las preguntas de soporte técnico adicionales y problemas que no califican para esta revisión específica. Para obtener una lista completa de los números de teléfono de servicio al cliente de Microsoft o para crear una solicitud de servicio independiente, visite el siguiente sitio Web de Microsoft:http://support.microsoft.com/contactus/?ws=supportNota: El formulario de "Descarga de Hotfix disponible" muestra los idiomas para los que el Hotfix está disponible. Si no ve su idioma, es porque no hay una revisión para ese idioma. Versión del inglés de esta revisión tiene los atributos de archivo (o posterior) que figuran en la tabla siguiente. Las fechas y horas de estos archivos se muestran en hora universal coordinada (UTC). Al ver la información del archivo, se convierte en hora local. Para encontrar la diferencia entre la hora UTC y la hora local, utilice el Ficha zona horaria en la herramienta fecha y hora del Panel de Control. MDAC 2.7 SP1 Date Time Version Size File name -------------------------------------------------------- 13-Oct-2002 19:24 90,112 Dahotfix.exe 03-Jul-2003 04:09 2000.81.9031.51 372,736 Sqlsrv32.dll MDAC 2.8 Date Time Version Size File name -------------------------------------------------------- 31-Mar-2004 16:44 2000.85.1040.0 24,576 Odbcbcp.dll 31-Mar-2004 16:43 2000.85.1040.0 401,408 Sqlsrv32.dll
Nota: Para obtener una lista de todas las revisiones disponibles para MDAC 2.8, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
CORREGIR 839801 : existen revisiones de MDAC 2.8
Estado
Microsoft ha confirmado que se trata de un problema de los productos de Microsoft que se enumeran en la sección "Aplicable a". Este problema se corrigió en Microsoft Access componente 2.7 Service Pack 1 actualización de datos y Microsoft Data Access Components 2.8.
Más información
Vea el problema que se menciona en la sección "Síntomas" de este artículo sólo cuando tiene Microsoft Data Access componente (MDAC) 2.7 Service Pack 1 instalado en el equipo.
Pasos para reproducir el comportamiento
Utilice el código siguiente para reproducir el problema:
// ODBCTestCase.cpp : Defines the entry point for the console application.
// #include "stdafx.h" #include "windows.h" #include "sqlext.h" #include "sql.h" #include "stdlib.h" void GetSQLError(); long InitializeEnvironment(); long Connect(BOOL lbUseDSN); long Disconnect(); int ExecuteProcedure(); SQLHENV ghEnvironment = NULL; SQLHDBC ghConnection = NULL; HSTMT ghStatement = NULL; /********************************************** * main **********************************************/ int main(int argc, char* argv[]) { BOOL lbTransaction = TRUE; BOOL lbUseDSN = FALSE; long lValue =0; if(argc > 1) { if(strcmp(argv[1], "DSN") == 0) lbUseDSN = TRUE; if(argc > 2) { if(strcmp(argv[2], "TRAN") == 0) lbTransaction = TRUE; } } if(InitializeEnvironment() == 0) { for(long llSub = 0; llSub < 2; llSub++) { if(Connect(lbUseDSN) == 0) { if(lbTransaction) SQLSetConnectOption(ghConnection, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF); //SQLGetConnectAttr(ghConnection,SQL_ATTR_AUTOCOMMIT,&lValue,0,NULL); ExecuteProcedure(); if(lbTransaction) { SQLTransact(ghEnvironment, ghConnection, SQL_COMMIT); //If you do not call the following, the problem does not occur: SQLSetConnectOption(ghConnection, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_ON); //If you call the following the problem does not occur: //SQLSetConnectOption(ghConnection, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF); //SQLGetConnectAttr(ghConnection,SQL_ATTR_AUTOCOMMIT,&lValue,0,NULL); } Disconnect(); } } SQLFreeHandle(SQL_HANDLE_ENV, ghEnvironment); } return 0; } /********************************************** * InitializeEnvironment **********************************************/ long InitializeEnvironment() { if (!SQL_SUCCEEDED(SQLSetEnvAttr(NULL, SQL_ATTR_CONNECTION_POOLING, (SQLPOINTER)SQL_CP_ONE_PER_DRIVER, SQL_IS_INTEGER))) { GetSQLError(); return 8; } if(!SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_ENV, NULL, &ghEnvironment))) { GetSQLError(); return 8; } if(!SQL_SUCCEEDED(SQLSetEnvAttr(ghEnvironment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC2, SQL_IS_INTEGER))) { GetSQLError(); return 8; } if (!SQL_SUCCEEDED(SQLSetEnvAttr(ghEnvironment, SQL_ATTR_CP_MATCH, (SQLPOINTER) SQL_CP_STRICT_MATCH , //(SQLPOINTER) SQL_CP_RELAXED_MATCH , SQL_IS_INTEGER))) { GetSQLError(); return 8; } return 0; } /********************************************** * Connect **********************************************/ long Connect(BOOL lbUseDSN) { SQLCHAR lszOutConnectString[1024]; SQLSMALLINT llReturnLength; SQLAllocHandle(SQL_HANDLE_DBC, ghEnvironment, &ghConnection); // If you set the isolation before opening the connection, no error reported. // Customer cannot set this attribute before opening connection because the object //is running under COM+, and under COM+ isolation levels automatically are set to serializable //if(!SQL_SUCCEEDED(::SQLSetConnectAttr(ghConnection, SQL_ATTR_TXN_ISOLATION, (SQLPOINTER)SQL_TXN_READ_COMMITTED , SQL_IS_INTEGER))) //{ // GetSQLError(); // return 8; //} if(lbUseDSN) { int iReturn = ::SQLConnect(ghConnection, (SQLCHAR*)"LocalCPR", SQL_NTS, (SQLCHAR*)"sa", SQL_NTS, (SQLCHAR*)"password1", SQL_NTS); if(!SQL_SUCCEEDED(iReturn)) { GetSQLError(); return 8; } } else { if(!SQL_SUCCEEDED(SQLDriverConnect(ghConnection, NULL, (SQLCHAR*)"DSN=LocalCPR;UID=sa;PWD=password1;", SQL_NTS, lszOutConnectString, 1024, &llReturnLength, SQL_DRIVER_NOPROMPT))) { GetSQLError(); return 8; } } SQLAllocStmt(ghConnection, &ghStatement); //If you set the isolation after you open the connection, you see the problem. if(!SQL_SUCCEEDED(::SQLSetConnectAttr(ghConnection, SQL_ATTR_TXN_ISOLATION, (SQLPOINTER)SQL_TXN_READ_COMMITTED , SQL_IS_INTEGER))) { GetSQLError(); return 8; } return 0; } /********************************************** * Disconnect **********************************************/ long Disconnect() { if(ghStatement) { if(!SQL_SUCCEEDED(SQLFreeHandle(SQL_HANDLE_STMT, ghStatement))) { GetSQLError(); return 8; } ghStatement = NULL; } if(ghConnection) { ::SQLDisconnect(ghConnection); if(!SQL_SUCCEEDED(SQLFreeHandle(SQL_HANDLE_DBC, ghConnection))) { GetSQLError(); return 8; } ghConnection = NULL; } return 0; } /********************************************** * ExecuteProcedure **********************************************/ int ExecuteProcedure() { SQLINTEGER mlIndicator = 0; SQLRETURN lnSqlRetCd = SQL_SUCCESS; ::SQLFreeStmt(ghStatement, SQL_CLOSE); ::SQLFreeStmt(ghStatement, SQL_UNBIND); /*****************************************************************/ /* Execute Procedure /*****************************************************************/ RETCODE llDbRetCd = SQLExecDirect(ghStatement, (SQLCHAR*)"SELECT * From Table1", SQL_NTS); if((llDbRetCd != SQL_SUCCESS) && (llDbRetCd != SQL_SUCCESS_WITH_INFO)) { GetSQLError(); return 8; } /*****************************************************************/ /* Bind return Value /*****************************************************************/ char lszReturnBuf[300]; SDWORD lSts; llDbRetCd = SQLBindCol(ghStatement, 1, SQL_C_TCHAR, &lszReturnBuf, 300, &lSts); if ((llDbRetCd != SQL_SUCCESS) && (llDbRetCd != SQL_SUCCESS_WITH_INFO)) { GetSQLError(); return 8; } /*****************************************************************/ /* Fetch Result /*****************************************************************/ llDbRetCd = SQLFetch(ghStatement); if ((llDbRetCd != SQL_SUCCESS) && (llDbRetCd != SQL_SUCCESS_WITH_INFO)) { GetSQLError(); return 8; } printf("Output Value : %s\n",lszReturnBuf); return 0; } /********************************************** * GetSQLError **********************************************/ void GetSQLError() { long llDbErrCd = 0; short llRetMsgLen = 0; char lszSqlErrMsg[255]; char lszSqlMsg[255]; SQLError(ghEnvironment, ghConnection, ghStatement, (SQLCHAR*) lszSqlErrMsg, &llDbErrCd, (SQLCHAR*) lszSqlMsg, 255, &llRetMsgLen); printf(lszSqlErrMsg); printf(lszSqlMsg); }