อาการ
เมื่อคุณพยายามที่จะตั้งค่าแอตทริบิวต์การเชื่อมต่อของการเชื่อมต่อ ODBC ที่เชื่อมต่อร่วมกันถูกเปิดใช้งาน โดยใช้โปรแกรมควบคุม ODBC API ด้วยโปรแกรมควบคุม ODBC เซิร์ฟเวอร์ SQL ของ Microsoft คุณได้รับข้อความแสดงข้อผิดพลาดต่อไปนี้:
IM006 SQLSetConnectAttr ขับขี่รถยนต์ [Microsoft] [ตัวจัดการโปรแกรมควบคุม ODBC] ล้มเหลว
หมายเหตุ เอกสารประกอบของโปรแกรมควบคุม ODBC ที่กล่าวถึงว่า ข้อความที่เป็นข้อความข้อมูล อย่างไรก็ตาม คุณได้รับข้อความเป็นข้อความข้อผิดพลาด
ปัญหานี้อาจเกิดขึ้นหากมีเงื่อนไขต่อไปนี้ทั้งหมด:-
คุณสามารถทำการเชื่อมต่อกับชื่อแหล่งข้อมูล (DSN) โดยใช้โปรแกรมควบคุม ODBC SQLConnect API
-
หนึ่งในคุณสมบัติเริ่มต้นของ dsn ของ (ตัวอย่างเช่นตัวเลือกค่า null ใช้ ANSI, paddings และคำเตือน) ถูกปิดใช้งาน
-
เปิดใช้งานการทำพูลเก็บการเชื่อมต่อสำหรับหมายเลขอ้างอิงของสภาพแวดล้อม
-
มีกำหนดแอททริบิวต์ระดับการแยกธุรกรรมของการเชื่อมต่อหลังจากที่คุณเปิดการเชื่อมต่อ โดยใช้ SQLConnect
-
ทรานแซคชันฐานข้อมูลจะดำเนินการ
วิธีแก้ปัญหา
เมื่อต้องการหลีกเลี่ยงปัญหานี้ ให้ทำตามขั้นตอนเหล่านี้:
-
ปิดใช้งานตัวเลือกสำหรับการเชื่อมต่อ ODBC การทำพูลเก็บการเชื่อมต่อ
หมายเหตุ การปิดใช้งานการทำพูลเก็บการเชื่อมต่ออาจมีผลกระทบต่อประสิทธิภาพการทำงานของโปรแกรมประยุกต์ของคุณ -
หลังจากที่คุณยอมรับธุรกรรม ไม่เปิดตัวเลือกการยอมรับโดยอัตโนมัติ
-
ตั้งค่าระดับการแยกธุรกรรมก่อนที่จะเปิดการเชื่อมต่อ ODBC
-
ใช้การเชื่อมต่อ DSN น้อยแทนที่จะได้รับการเชื่อมต่อ ODBC กับ DSN
การแก้ปัญหา
มีโปรแกรมแก้ไขด่วนที่รองรับพร้อมให้บริการจาก Microsoft อย่างไรก็ตาม โปรแกรมแก้ไขด่วนนี้มุ่งหวังเพื่อการแก้ไขเฉพาะปัญหาที่อธิบายไว้ในบทความนี้ ใช้ hotfix นี้เฉพาะกับระบบต่าง ๆ ที่พบปัญหานี้
หากโปรแกรมแก้ไขด่วนพร้อมสำหรับการดาวน์โหลด คุณจะเห็นส่วน "มีโปรแกรมแก้ไขด่วนพร้อมสำหรับการดาวน์โหลด" ที่ด้านบนของบทความฐานข้อมูลองค์ความรู้นี้ หากส่วนนี้ไม่ปรากฏขึ้น ส่งคำขอถึงฝ่ายบริการและการสนับสนุนลูกค้าของ Microsoft และวิธีการขอรับโปรแกรมแก้ไขด่วน หมายเหตุ ถ้ามีปัญหาอื่น ๆ เกิดขึ้น หรือถ้าจำเป็นต้องแก้ไขปัญหาใด ๆ คุณอาจต้องสร้างคำขอรับบริการแยกต่างหาก จะมีค่าใช้จ่ายในการสนับสนุนปกติกับคำถามเพิ่มเติมและเรื่องอื่น ๆ ที่ไม่มีสิทธิได้รับโปรแกรมแก้ไขด่วนเฉพาะนี้ สำหรับรายชื่อทั้งหมด ของหมายเลขโทรศัพท์ของฝ่ายบริการลูกค้าของ Microsoft และการสนับสนุน หรือ เพื่อสร้างการร้องขอบริการแยกต่างหาก แวะไปที่เว็บไซต์ต่อไปนี้ของ Microsoft:http://support.microsoft.com/contactus/?ws=supportหมายเหตุ แบบฟอร์ม "มีโปรแกรมแก้ไขด่วนพร้อมสำหรับการดาวน์โหลด" แสดงภาษาที่โปรแกรมแก้ไขด่วนพร้อมใช้งาน ถ้าคุณไม่เห็นภาษาของคุณ อาจเป็น เพราะไม่มีโปรแกรมแก้ไขด่วนพร้อมใช้งานสำหรับภาษานั้น รุ่นแบบภาษาอังกฤษของโปรแกรมแก้ไขนี้มีแอตทริบิวต์ของแฟ้ม (หรือรุ่นที่ใหม่กว่า) ซึ่งแสดงอยู่ในตารางต่อไปนี้ วันและเวลาสำหรับแฟ้มเหล่านี้จะแสดงรายการในเวลามาตรฐานสากล (UTC) เมื่อคุณดูข้อมูลแฟ้ม ระบบจะแปลงข้อมูลนี้เป็นเวลาท้องถิ่น เมื่อต้องการค้นหาความแตกต่างระหว่างเวลา UTC กับเวลาท้องถิ่น ใช้ แท็บโซนเวลาในเครื่องมือ'วันและเวลา'ใน'แผงควบคุม' 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
หมายเหตุ สำหรับรายการทั้งหมดโปรแกรมแก้ไขด่วนพร้อมใช้งานสำหรับ MDAC 2.8 คลิกหมายเลขบทความต่อไปนี้เพื่อดูบทความในฐานความรู้ของ Microsoft:
839801แก้ไข: โปรแกรมแก้ไขด่วนพร้อมใช้งานสำหรับ MDAC 2.8
สถานะ
Microsoft ได้ยืนยันว่า นี่เป็นปัญหาในผลิตภัณฑ์ของ Microsoft ซึ่งแสดงไว้ในส่วน "ใช้กับ" ปัญหานี้ได้รับการแก้ไขใน Microsoft Access คอมโพเนนต์ 2.7 Service Pack 1 ที่รีเฟรชข้อมูลและ 2.8 คอมโพเนนต์การเข้าถึงข้อมูล Microsoft
ข้อมูลเพิ่มเติม
คุณเห็นปัญหาที่กล่าวถึงในส่วน "อาการ" ของบทความนี้เฉพาะเมื่อคุณมี Microsoft ข้อมูล Access คอมโพเนนต์ (MDAC) 2.7 Service Pack 1 ติดตั้งอยู่บนคอมพิวเตอร์ของคุณ
ขั้นตอนในการทบทวนเกิดลักษณะการทำงาน
ใช้รหัสต่อไปนี้เพื่อสร้างปัญหา:
// 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); }