FIX: Perdita di memoria nel driver ODBC per Jet con SQL_NUMERIC o SQL_C_BINARY dati

Il presente articolo è stato tradotto tramite il software di traduzione automatica di Microsoft e non da una persona. Microsoft offre sia articoli tradotti da persone fisiche sia articoli tradotti automaticamente da un software, in modo da rendere disponibili tutti gli articoli presenti nella nostra Knowledge Base nella lingua madre dell’utente. Tuttavia, un articolo tradotto in modo automatico non è sempre perfetto. Potrebbe contenere errori di sintassi, di grammatica o di utilizzo dei vocaboli, più o meno allo stesso modo di come una persona straniera potrebbe commettere degli errori parlando una lingua che non è la sua. Microsoft non è responsabile di alcuna imprecisione, errore o danno cagionato da qualsiasi traduzione non corretta dei contenuti o dell’utilizzo degli stessi fatto dai propri clienti. Microsoft, inoltre, aggiorna frequentemente il software di traduzione automatica.

273772
Questo articolo è stato archiviato. L’articolo, quindi, viene offerto “così come è” e non verrà più aggiornato.
Sintomi
Una perdita di memoria si verifica quando si chiama la funzione SQLBindParameter nel driver ODBC di Jet e quando si associa a un tipo di dati SQL di SQL_NUMERIC o quando si associa SQL_C_BINARY a SQL_WCHAR.

Se si utilizza il Performance Monitor (PerfMon) per controllare il byte privati per il processo, vengono visualizzati un aumento della memoria graduale ma costante, e la memoria non viene liberata quando chiude le istruzioni o le connessioni.
Cause
Buffer vengono utilizzati all'interno il driver ODBC di Jet consente di convertire i tipi di dati di parametro ODBC tipi di dati nativo per il modulo di gestione di database Jet. I buffer vengono fatto riferimento tramite puntatori gestiti sull'handle di istruzione, come parte i descrittori di parametro (IPDs).

In genere, il codice verifica se il puntatore già fa riferimento a un buffer di memoria valida e quindi riutilizza il buffer se esiste. Tuttavia, quando si associa un tipo di dati SQL_NUMERIC o, quando si esegue l'associazione SQL_C_BINARY a SQL_WCHAR nuova memoria è allocata e assegnata il puntatore del mouse senza verificare prima, e il valore precedente verrà sovrascritto.
Risoluzione
Questo problema è stato risolto nei service pack più recenti per Windows 2000 e MDAC 2.5.
  • Per risolvere questo problema è necessario ottenere la versione più recente del service pack per Windows 2000. Per ulteriori informazioni, fare clic sul numero dell'articolo della Microsoft Knowledge Base riportato di seguito riportato:
    260910Come ottenere Windows 2000 Service Pack più recente
  • Per risolvere il problema, ottenere il service pack più recente per Microsoft Data Access Components 2.5. Per ulteriori informazioni, fare clic sul numero dell'articolo della Microsoft Knowledge Base riportato di seguito riportato:
    293312INFORMAZIONI: Come ottenere il più recente MDAC 2.5 Service Pack
La versione inglese di questa correzione deve essere di avere i seguenti attributi di file o versioni successive:
   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				
Nota : questo hotfix richiede Microsoft Data Access Components (MDAC) 2.5 Service Pack 1 (SP1) o successiva a causa delle dipendenze sugli altri file di introdotto con MDAC 2.5 SP1. Vi è alcuna correzione disponibili che è possibile applicare direttamente a MDAC 2.5.

Per installare questo aggiornamento rapido (hotfix) in una piattaforma di Microsoft Windows 2000, eseguire il pacchetto di installazione di aggiornamento rapido (hotfix) (Q273772_W2K_SP2_x86_en.EXE). Sebbene l'aggiornamento rapido stesso non è dipendente dalla piattaforma, il pacchetto di installazione aggiornamento rapido (hotfix) è progettato per essere eseguito solo su piattaforme Windows 2000 e non verrà eseguito in Microsoft Windows NT 4.0, Microsoft Windows 95 o piattaforme Microsoft Windows 98. MDAC contiene i file di file protetti di sistema ed è possibile sostituire solo i file da un programma di installazione hotfix con firma digitale in Windows 2000. Il file di aggiornamento rapido (hotfix) di autonomo viene fornito anche in modo che è possibile copiare il file direttamente su piattaforme Windows NT 4.0, Windows 95 o Windows 98.


PER RISOLVERE IL PROBLEMA

Non è disponibile alcuna soluzione per questo problema.
Status
Microsoft ha confermato che questo problema riguarda i prodotti Microsoft elencati all'inizio di questo articolo. Questo problema è stato innanzitutto corretto in Microsoft Data Access Components 2.5 Service Pack 2 e Microsoft Windows 2000 Service Pack 2.
Informazioni
Se si esamina la memoria per il processo periodicamente durante l'esecuzione del processo, si notare che un numero sempre maggiore di 0 x 100000 (1048576) allocazioni di byte. Se il processo continua a eseguire, il processo eventualmente esaurisce la memoria e non risponde (si blocca) o ha esito negativo.

Procedura per riprodurre il problema

  1. Copiare il codice che segue in un'applicazione console di Microsoft Visual c ++ e quindi compilare il codice. Si noti, che potrebbe essere necessario modificare il nome dell'origine dati, l'id utente e la password.
    #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);}						
    Nota : È possibile utilizzare la costante LEAK_NUMERIC per dimostrare il SQL_NUMERIC oppure SQL_C_BINARY perdita.
  2. Creare un nuovo vuoto verrà database come specificato dalla posizione nella stringa di connessione.
  3. Avviare l'esecuzione del codice e quindi utilizzare Performance Monitor per controllare il contatore Byte privati per il processo.

    Si noti che il contatore Byte privati raggiunge costantemente durante l'esecuzione del codice.
Jet odbc driver odbcjt32.dll memoria perdita sql_numeric sql_c_binary sqlbindparameter parametri

Avviso: questo articolo è stato tradotto automaticamente

Proprietà

ID articolo: 273772 - Ultima revisione: 01/10/2015 12:49:07 - Revisione: 2.2

  • Driver Microsoft Open Database Connectivity per 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 KbMtit
Feedback