Sümptomid
Kui püüate määrata ühenduse atribuudi ODBC ühenduse, kus ühenduse ühiskasutus on lubatud, kasutades koos Microsoft SQL serveri ODBC-draiver ODBC draiver API, kuvatakse järgmine tõrketeade:
IM006 [Microsoft] [ODBC draiver Manager] draiveri toiming SQLSetConnectAttr nurjus
Märkus. ODBC-draiver dokumentatsiooni mainib sõnum on teate. Siiski kuvatakse teade kui kuvatakse tõrketeade.
See probleem võib ilmneda juhul, kui täidetud on järgmised tingimused:-
Andmeallika nimi (DSN) ühendus teha SQLConnect ODBC draiver API abil.
-
Üks DNS (nt suvand Use ANSI tühiväärtusi, paddings ja hoiatused ) vaikeatribuudid on keelatud.
-
Ühenduse ühiskasutus on lubatud keskkonnas pide.
-
Ühendus tehingu isolatsiooni taseme atribuut on seatud, pärast seda, kui avate ühenduse SQLConnect abil.
-
Andmebaasi tehingulogi on läbi.
Lahendus
Selle probleemi lahendamiseks toimige järgmiselt.
-
Keelake ühenduse ühiskasutus ODBC ühenduse võimalus.
Märkus. Ühenduse ühiskasutus keelamine võib mõjutada rakenduse jõudlust. -
Kui sa tehingu, lülitage sisse suvand automaatne kinnitamine.
-
Määrata tehingu isolatsiooni enne, kui avate ODBC-ühendus.
-
Kasutage selle asemel et saada DSN ODBC ühenduse DNS-vähem ühendust.
Lahendus
Toetatud käiguparandus on saadaval Microsoftilt. See kiirparandus on ette nähtud üksnes käesolevas artiklis kirjeldatud probleemi lahendamiseks. Kasutage seda parandust ainult selle konkreetse probleemiga süsteemides.
Kui kiirparandus on allalaadimiseks saadaval, on selle teabebaasi artikli alguses jaotis "Kiirparandus on allalaadimiseks saadaval". Kui seda jaotist ei ole, saatke Microsofti klienditeenindusele ja -toele taotlus kiirparanduse hankimiseks. Märkus. Kui ilmneb veel probleeme või kui on tarvis teha tõrkeotsing, peate looma eraldi tugiteenuse taotluse. Tavapärane tugiteenuse tasu kehtib täiendavatele tugiteenustega seotud küsimustele ning probleemidele, mis pole lahendatavad konkreetse kiirparandusega. Täieliku loetelu Microsofti klienditeeninduse ja -toe telefoninumbrite või eraldi tugiteenuse taotluse loomiseks külastage järgmist Microsofti veebisaiti:http://support.microsoft.com/contactus/?ws=supportMärkus. "Kiirparandus on allalaadimiseks saadaval" vormil kuvatakse keeled, mille jaoks kiirparandus on saadaval. Kui te ei näe oma keelt, ei ole kiirparandus selles keeles saadaval. See parandus inglise versioonil on failiatribuudid (või uuem) mis on loetletud järgmises tabelis. Kuupäevad ja kellaajad need failid on loetletud koordineeritud maailmaaja (UTC). Faili teabe vaatamisel teisendatakse see kohalikule ajale. UTC-aja ja kohaliku aja erinevuse väljaselgitamiseks kasutage seda Juhtpaneeli tööriista kuupäev ja kellaaeg vahekaarti ajavöönd . 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
Märkus. Kõiki Kiirparandusi, mis on saadaval MDAC 2.8 loendi saamiseks klõpsake Microsofti teabebaasi (Knowledge Base) artikli kuvamiseks järgmist artiklinumbrit:
839801 FIX: Kiirparandused on saadaval MDAC 2.8
Olek
Microsoft on kinnitanud, et see probleem esineb jaotises "Kehtib järgmiste toodete kohta" loetletud Microsofti toodetel. See probleem lahendati Microsoft andmete juurdepääsu komponendi 2.7 Service Pack 1 värskendada ja Microsoft Data Access Components 2.8.
Lisateabe saamiseks
Kuvatakse ainult kui teil on Microsoft Data Access komponentide (MDAC) 2.7 teie arvutisse on installitud hoolduspakett Service Pack 1 käesoleva artikli jaotises "Tunnused" kirjeldatud probleemi.
Sellise käitumise taasesilekutsumise juhised
Kasutage probleemi taasesilekutsumise järgmine kood:
// 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); }