Ihr Browser wird nicht unterstützt.

Sie müssen Ihren Browser aktualisieren, um die Website zu verwenden.

Aktualisieren Sie auf die neueste Version von Internet Explorer.

Update: Speicherleck in Jet ODBC-Treiber mit SQL_NUMERIC oder SQL_C_BINARY Daten

Wichtig: Dieser Artikel wurde maschinell und nicht von einem Menschen übersetzt. Die Microsoft Knowledge Base ist sehr umfangreich und ihre Inhalte werden ständig ergänzt beziehungsweise überarbeitet. Um Ihnen dennoch alle Inhalte auf Deutsch anbieten zu können, werden viele Artikel nicht von Menschen, sondern von Übersetzungsprogrammen übersetzt, die kontinuierlich optimiert werden. Doch noch sind maschinell übersetzte Texte in der Regel nicht perfekt, insbesondere hinsichtlich Grammatik und des Einsatzes von Fremdwörtern sowie Fachbegriffen. Microsoft übernimmt keine Gewähr für die sprachliche Qualität oder die technische Richtigkeit der Übersetzungen und ist nicht für Probleme haftbar, die direkt oder indirekt durch Übersetzungsfehler oder die Verwendung der übersetzten Inhalte durch Kunden entstehen könnten.

Den englischen Originalartikel können Sie über folgenden Link abrufen: 273772
Dieser Artikel wurde archiviert. Er wird im vorliegenden Zustand bereitgestellt und nicht mehr aktualisiert.
Problembeschreibung
Wenn Sie die Funktion SQLBindParameter in dem Jet ODBC-Treiber aufrufen und Sie an eine SQL-Datentyp SQL_NUMERIC oder beim Binden von SQL_C_BINARY an SQL_WCHAR binden, tritt ein Speicherverlust auf.

Wenn Sie den Systemmonitor (PerfMon), verwenden um die privaten Bytes für den Prozess zu überwachen, sehen Sie eine stufenweise aber stetigen Speicher erhöhen und der Speicher ist nicht freigegeben, wenn die Anweisungen oder Verbindungen schließen.
Ursache
Puffer werden in dem Jet ODBC-Treiber verwendet, damit die ODBC-Parameter-Datentypen in systemeigenen Datentypen für die Jet-Datenbankmodul zu konvertieren. Dieser Puffer werden über Zeiger auf das Anweisungshandle verwaltet, als Teil der Sicherheitsbeschreibungen Parameter (IPDs) verwiesen.

Normalerweise prüft der Code, wenn der Zeiger verweist bereits auf einen gültigen Speicherpuffer und dann den Puffer, wiederverwendet sofern vorhanden. Jedoch beim SQL_NUMERIC Datentyp zu binden oder beim Binden von SQL_C_BINARY an SQL_WCHAR, neuen Speicher reserviert und der Zeiger zugewiesen, ohne zuerst überprüfen, und der vorherige Wert überschrieben.
Lösung
Dieses Problem wird in den neuesten Service Packs für Windows 2000 und MDAC 2.5 behoben.
  • Installieren Sie das neueste Service Pack für Windows 2000, um dieses Problem zu beheben. Weitere Informationen finden Sie die folgende KB-Artikelnummer:
    260910Wie Sie das neueste Service Pack für Windows 2000 erhalten
  • Installieren Sie das neueste Servicepack für Microsoft Data Access Components 2.5, um dieses Problem zu beheben. Weitere Informationen finden Sie die folgende KB-Artikelnummer:
    293312INFO: Wie erhalten Sie die neueste MDAC 2.5 Servicepack
Die englische Version dieses Updates müsste die folgenden Dateiattribute oder höher:
   Date        Version       Size              File name       ---------------------------------------------------------------------   09/13/00    4.0.5708.0    270,608 bytes    Odbcjt32.dll   09/14/00    1.10.101.0    295,696 bytes    Q273772_W2K_SP2_x86_en.EXE				
Hinweis : dieser Hotfix erfordert Microsoft Data Access Components (MDAC) 2.5 Service Pack 1 (SP1) oder höher aufgrund von Abhängigkeiten von anderen Dateien mit MDAC 2.5 SP1 eingeführt. Es gibt kein Update verfügbar, die Sie direkt zu MDAC 2.5 anwenden können.

Führen Sie das Hotfix-Installer-Paket (Q273772_W2K_SP2_x86_en.EXE), um diesen Hotfix auf einem Microsoft Windows 2000-Plattform zu installieren. Der Hotfix selbst ist, zwar nicht plattformabhängige wird das Hotfix-Installer-Paket ist nur auf Windows 2000-Plattformen vorgesehen und wird auf Microsoft Windows NT 4.0, Microsoft Windows 95 oder Microsoft Windows 98-Plattformen nicht ausgeführt. MDAC enthält Datei geschützte Systemdateien, und Sie können diese Dateien nur ersetzen, indem eine digital signierte Hotfix-Installer unter Windows 2000. Die eigenständige Hotfix-Datei wird sowie bereitgestellt, sodass Sie die Datei direkt in Windows NT 4.0, Windows 95 oder Windows 98-Plattformen kopieren können.


PROBLEMUMGEHUNG

Es gibt keine Problemumgehung für dieses Problem.
Status
Microsoft hat bestätigt, dass es sich hierbei um ein Problem bei den in diesem Artikel genannten Microsoft-Produkten handelt. Dieses Problem wurde erstmals im Microsoft Data Access Components 2.5 Service Pack 2 und Microsoft Windows 2000 Service Pack 2.
Weitere Informationen
Den Speicher für den Prozess in regelmäßigen Abständen während der Prozess ausgeführt wird, Sie feststellen eine steigende Anzahl von 0 x 100000 (1048576) Bytezuweisungen. Wenn der Prozess ausgeführt weiterhin, das schließlich zuwenig Arbeitsspeicher ausgeführt wird und nicht mehr reagiert (hängt) oder fehlschlägt.

Schritte zum Reproduzieren des Verhaltens

  1. Kopieren Sie den Code, der in eine Microsoft Visual C++-Konsolenanwendung folgt, und kompilieren Sie den Code. Beachten Sie, dass Sie möglicherweise ändern Sie den Namen der Datenquelle, Benutzer-Id und das Kennwort müssen.
    #include <windows.h>#include <sql.h>#include <sqlext.h>#include <tchar.h>#include <stdlib.h>#include <stdio.h>#define LEAK_NUMERIC 1		//Use this to determine NUMERIC or BINARY leakvoid HandleError(SQLHANDLE	hHandle, SQLSMALLINT hType, RETCODE RetCode){	SQLSMALLINT	iRec = 0;	SQLINTEGER	iError;	TCHAR		szMessage[1000];	TCHAR		szState[SQL_SQLSTATE_SIZE];	if (RetCode == SQL_INVALID_HANDLE)	{		fprintf(stderr,"Invalid handle!\n");		return;	}	while (SQLGetDiagRec(hType,			 hHandle,			 ++iRec,			 (SQLCHAR *)szState,			 &iError,			 (SQLCHAR *)szMessage,			 (SQLSMALLINT)(sizeof(szMessage) / sizeof(TCHAR)),			 (SQLSMALLINT *)NULL) == SQL_SUCCESS)	{		fprintf(stderr,TEXT("[%5.5s] %s (%d)\n"),szState,szMessage,iError);	}}char* szConnStringIn = "Driver={Microsoft Access Driver (*.mdb)};DBQ=E:\\JetLeak\\TestDatabase.mdb";char* szDropTable = "DROP TABLE LeakTable";//char* szInsertStatement = "INSERT INTO LeakTable VALUES (?)";char* szSelectStatement = "SELECT * FROM LeakTable WHERE val1 = ?";const int nParamCount = 1; #if LEAK_NUMERICchar* szCreateTable = "CREATE TABLE LeakTable (val1 long)";#elsechar* szCreateTable = "CREATE TABLE LeakTable (val1 varchar(10))";#endifvoid main(int argc, char* argv[]){	SQLHENV henv;	SQLHDBC hdbc;	SQLHSTMT hstmt;	SQLRETURN nstatus;	char szConnStringOut[1024];	SQLSMALLINT cbConnOut;	SQLINTEGER status[nParamCount];#if LEAK_NUMERIC	SQLCHAR szParam[nParamCount][10] = {"12345"};#else	BYTE szParam[nParamCount][10] = {0x31,0x33,0x34,0x39};#endif    	//Not checking the return codes in some cases for clarity.		nstatus = SQLAllocHandle(SQL_HANDLE_ENV,NULL,&henv);	nstatus = SQLSetEnvAttr(henv,SQL_ATTR_ODBC_VERSION,(SQLPOINTER) SQL_OV_ODBC3,0);	nstatus = SQLAllocHandle(SQL_HANDLE_DBC,henv,&hdbc);	nstatus = SQLDriverConnect(hdbc,			NULL,			(SQLCHAR*) szConnStringIn,			SQL_NTS,			(SQLCHAR*) szConnStringOut,			sizeof (szConnStringOut),			&cbConnOut,			SQL_DRIVER_COMPLETE);								if (nstatus != SQL_SUCCESS && nstatus != SQL_SUCCESS_WITH_INFO)	{		HandleError(hdbc,SQL_HANDLE_DBC,nstatus);		return;	}	nstatus = SQLAllocHandle(SQL_HANDLE_STMT,hdbc,&hstmt);		nstatus = SQLExecDirect(hstmt, (SQLCHAR*) szDropTable, SQL_NTS);	nstatus = SQLExecDirect(hstmt, (SQLCHAR*) szCreateTable, SQL_NTS);	if (!SQL_SUCCEEDED(nstatus))	{		HandleError(hstmt,SQL_HANDLE_STMT,nstatus);	}	int i;	//only one parameter in this case	for (i=0; i < nParamCount; i++)	{		status[i] = SQL_NTS;#if LEAK_NUMERIC		nstatus = SQLBindParameter(hstmt,			i+1,			SQL_PARAM_INPUT,			SQL_C_CHAR,				SQL_NUMERIC, 			10, 			0,			szParam[i],			10,			&status[i]);#else		nstatus = SQLBindParameter(hstmt,			i+1,			SQL_PARAM_INPUT,			SQL_C_BINARY,				SQL_WCHAR,			10, 			0,			szParam[i],			10,			&status[i]);#endif			}	nstatus = SQLPrepare(hstmt,(SQLCHAR*) szSelectStatement, SQL_NTS);	if (nstatus != SQL_SUCCESS)	{		HandleError(hstmt,SQL_HANDLE_STMT,nstatus);	}	for (i=0; i < 100000; i++)	{		if (i % 100 == 0)		{			printf("Selected %d times\n", i);			//printf("Inserted %d records\n", i);			Sleep(100);		}		nstatus = SQLExecute(hstmt);		if (nstatus != SQL_SUCCESS)		{			HandleError(hstmt,SQL_HANDLE_STMT,nstatus);		}		SQLFreeStmt(hstmt, SQL_CLOSE);	}	nstatus = SQLExecDirect(hstmt, (SQLCHAR*) "DELETE FROM LeakTable", SQL_NTS);	if (nstatus != SQL_SUCCESS)	{		HandleError(hstmt,SQL_HANDLE_STMT,nstatus);	}	SQLFreeStmt(hstmt, SQL_CLOSE);	SQLDisconnect(hdbc);}						
    Hinweis : können Sie die LEAK_NUMERIC-Konstante SQL_NUMERIC oder SQL_C_BINARY Speicherverlust veranschaulichen.
  2. Erstellen Sie eine neue leere Microsoft Access-Datenbank wie angegeben durch die Position in der Verbindungszeichenfolge.
  3. Starten der Code ausgeführt wird, und dann mithilfe des Systemmonitors um den Indikator Private Bytes für den Prozess zu überwachen.

    Beachten Sie, dass der Indikator Private Bytes stetig zunimmt, während der Code ausgeführt wird.
Jet ODBC-Treiber odbcjt32.dll Memory Leck Sql_numeric Sql_c_binary Sqlbindparameter Parameter

Warnung: Dieser Artikel wurde automatisch übersetzt.

Eigenschaften

Artikelnummer: 273772 – Letzte Überarbeitung: 01/10/2015 12:49:02 – Revision: 2.2

  • Microsoft Open Database Connectivity-Treiber für Access 4.0
  • Microsoft Data Access Components 2.5
  • Microsoft Data Access Components 2.5 Service Pack 1
  • kbnosurvey kbarchive kbmt kbhotfixserver kbqfe kbbug kbfix kbjet kbmdac250sp2fix kbwin2000presp2fix KB273772 KbMtde
Feedback