Príznaky
Keď sa pokúsite nastaviť atribút pripojenie ODBC pripojenia, ak je zapnuté na združovanie pomocou API ovládač ODBC ovládač ODBC Microsoft SQL Server, zobrazí nasledujúce chybové hlásenie:
IM006 [Microsoft] [ovládač ODBC manažér] ovládača funkcia SQLSetConnectAttr zlyhala
Poznámka: Ovládač ODBC dokumentáciu uvádza, že správa je informačné hlásenie. Hlásenie chýb správe.
Tento problém sa môže vyskytnúť, ak sú splnené všetky nasledujúce podmienky:-
Vykonáte pripojenie názov zdroja údajov (DSN) pomocou API ovládač ODBC SQLConnect.
-
Medzi predvolené vlastnosti DSN (napr. možnosť použiť hodnoty, vyplnenia a upozornenia ) je vypnutá.
-
Rukoväť prostredia je zapnuté združovanie.
-
Transakcia izolácia úrovni pripojenia je nastavený atribút po otvorení pripojenie pomocou SQLConnect.
-
Vykonáva transakcií databázy.
Alternatívne riešenie
Ak chcete vyriešiť tento problém, postupujte nasledovne:
-
Vypnite možnosť pripojenia ODBC združovanie.
Poznámka: Deaktivovať združovanie môže ovplyvniť výkon aplikácie. -
Keď odovzdáte transakcií, Nezapínajte možnosť Automatické potvrdenie.
-
Nastaviť úroveň izolácie transakcie otvoriť pripojenie ODBC.
-
Namiesto získanie pripojenie ODBC DSN použiť DSN-menej pripojenia.
Riešenie
Od spoločnosti Microsoft je k dispozícii podporovaná rýchla oprava. Táto rýchla oprava je však určená iba opravu problému, ktorý je popísaný v tomto článku. Rýchlu opravu použite len v počítačoch s týmto konkrétnym problémom.
Ak je rýchla oprava k dispozícii na stiahnutie, na začiatku tohto článku databázy Knowledge Base sa nachádza časť „K díspozícii je rýchla oprava na stiahnutie“. Ak sa táto sekcia nezobrazuje, odošlite požiadavku na služby zákazníkom spoločnosti Microsoft a podporu získať rýchlu opravu. Poznámka: Ak sa vyskytnú ďalšie problémy alebo ak je potrebné riešiť problémy, je možné, že budete musieť vytvoriť samostatnú servisnú požiadavku. Na ďalšie žiadosti o podporu a problémy, ktoré sa netýkajú tejto konkrétnej rýchlej opravy, sa vzťahujú zvyčajné poplatky za poskytnutie technickej podpory. Úplný zoznam telefónnych čísel služieb zákazníkom spoločnosti Microsoft a podpora alebo vytvoriť samostatnú servisnú požiadavku, nájdete na webovej lokalite spoločnosti Microsoft:http://support.microsoft.com/contactus/?ws=supportPoznámka: Formulár "Prevzatie dostupnej rýchlej opravy" sa zobrazuje pre jazyky, pre ktoré je rýchla oprava k dispozícii. Ak nemôžete nájsť požadovaný jazyk, znamená to, že rýchla oprava nie je pre tento jazyk k dispozícii. Anglická verzia tejto opravy má atribúty súborov (alebo novšie) uvedené v nasledujúcej tabuľke. Dátumy a časy jednotlivých súborov sú uvedené v koordinovaný svetový čas (UTC). Pri zobrazení informácií o súbore sa dátumy a čas prevedú na miestny čas. Ak chcete vyhľadať rozdiely medzi časom UTC a miestnym časom, použite Časové pásmo kartu v nástroji dátum a čas v ovládacom paneli. 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
Poznámka: Zoznam všetkých dostupných MDAC 2.8 rýchlych, po kliknutí na nasledovné číslo článku publikovaného v databáze Microsoft Knowledge Base:
839801 opraviť: rýchle opravy sú k dispozícii na MDAC 2.8
Stav
Spoločnosť Microsoft potvrdila, že ide o problém v produktoch spoločnosti Microsoft, ktoré sú uvedené v časti "Vzťahuje sa na". Tento problém bol opravený v Microsoft Data Access súčasti 2.7 Service Pack 1 obnoviť Microsoft Data Access Components 2.8.
Ďalšie informácie
Sa vyskytol problém, ktorý je uvedený v časti "Príznaky" tohto článku, iba ak máte Microsoft Data Access súčasti (MDAC) 2.7 Service Pack 1 v počítači nainštalovaný.
Kroky na reprodukovanie správania
Reprodukovať problém, použite nasledujúci kód:
// 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); }