[FIX] SERVERDATAONINSERT と 255 バイトを超える列サイズで MDAC SQLOLEDB Provider がメモリ リークを起こす

この記事は、以前は次の ID で公開されていました: JP302995
この資料は、アーカイブされました。これは "現状のまま" で提供され、更新されることはありません。
現象
列サイズが 255 バイトを超える場合に、Microsoft OLE DB Provider for SQL Server (SQLOLEDB) で SERVERDATAONINSERT を使うと、メモリ リークが発生します。
解決方法
この問題を解決するために、SQL Server 2000 の最新の Service Pack の適用をお願いいたします。
最新の SQL Server サービスパックのダウンロードおよびインストールについて詳しくは以下をご覧下さい。
状況
弊社では、これを Microsoft SQL Server version 2000 の問題として確認しています。
この問題は、Microsoft SQL Server version 2000 Service Pack 2 で修正されています。
詳細

問題の再現手順

  1. Microsoft SQL Server 2000 で、以下のテーブルを作成します。
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[STATEMIN1]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)drop table [dbo].[STATEMIN1]<BR/>GOCREATE TABLE [dbo].[STATEMIN1] (	[messagekey] [int] IDENTITY (1, 1) NOT NULL ,	[message] [varchar] (2000) NOT NULL ) ON [PRIMARY]GOALTER TABLE [dbo].[STATEMIN1] WITH NOCHECK ADD 	CONSTRAINT [PK_STATEMIN1] PRIMARY KEY  CLUSTERED 	(		[messagekey]	)  ON [PRIMARY] GO
  2. 以下のコードを Microsoft Visual C++ Win32 console application に貼り付けて、コードをコンパイルします。

    : データソース名、ユーザー ID、およびパスワードを変更する必要があります。
    #include <afx.h>#include <assert.h>#include <iostream>#include <atldbcli.h>#include <objbase.h>const ULONG nInitProps = 4;const ULONG nPropSet = 1;const ULONG nParams = 3; //コマンドのパラメータ数const ULONG nProps = 5;struct StateIn	{	UINT uiMessageKey;	TCHAR pszMessage[257];};int main(void){   	CCommand<CManualAccessor,CRowset,CNoMultipleResults> rs;	CDataSource m_connect;	CSession m_session;		DBPROP    InitProperties[nProps];	DBPROPSET   rgInitPropSet;	USES_CONVERSION;	HRESULT   hr;	hr = CoInitialize(NULL);	for (ULONG i = 0; i < nProps; i++ )	{		VariantInit(&InitProperties[i].vValue);		InitProperties[i].dwOptions = DBPROPOPTIONS_REQUIRED;		InitProperties[i].colid = DB_NULLID;	}	InitProperties[0].dwPropertyID = DBPROP_INIT_PROMPT;	InitProperties[0].vValue.vt = VT_I2;	InitProperties[0].vValue.iVal = DBPROMPT_NOPROMPT;	InitProperties[1].dwPropertyID = DBPROP_INIT_DATASOURCE;	InitProperties[1].vValue.vt = VT_BSTR;	InitProperties[1].vValue.bstrVal =          SysAllocString(OLESTR("servername"));                            // サーバー名	InitProperties[2].dwPropertyID = DBPROP_INIT_CATALOG;	InitProperties[2].vValue.vt = VT_BSTR;	InitProperties[2].vValue.bstrVal = SysAllocString(L"database");    // データベース名	InitProperties[2].dwOptions = DBPROPOPTIONS_REQUIRED;	InitProperties[2].colid = DB_NULLID;	InitProperties[3].dwPropertyID = DBPROP_AUTH_USERID;	InitProperties[3].vValue.vt = VT_BSTR;	InitProperties[3].vValue.bstrVal = SysAllocString(OLESTR("sa"));    // ユーザー ID	InitProperties[4].dwPropertyID = DBPROP_AUTH_PASSWORD;	InitProperties[4].vValue.vt = VT_BSTR;	InitProperties[4].vValue.bstrVal = SysAllocString(OLESTR(""));      // パスワード		rgInitPropSet.guidPropertySet = DBPROPSET_DBINIT;	rgInitPropSet.cProperties = nProps;	rgInitPropSet.rgProperties = InitProperties;	char szProgID[100] = {0};	strcpy(szProgID,"SQLOLEDB");	CLSID clsid;	WCHAR   wszProgId[100] = {0};	MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szProgID, -1,   wszProgId, 100);	hr = CLSIDFromProgID(wszProgId, &clsid);	hr = m_connect.Open(clsid,&rgInitPropSet);	hr = m_session.Open(m_connect);	SysFreeString(InitProperties[1].vValue.bstrVal);	SysFreeString(InitProperties[2].vValue.bstrVal);	SysFreeString(InitProperties[3].vValue.bstrVal);	SysFreeString(InitProperties[4].vValue.bstrVal);	DWORD dwStatus;	dwStatus = DBSTATUS_S_IGNORE;	CDBPropSet propset(DBPROPSET_ROWSET);	propset.AddProperty(DBPROP_IRowsetChange, true);	propset.AddProperty(DBPROP_IRowsetUpdate, false);	propset.AddProperty(DBPROP_UPDATABILITY,		DBPROPVAL_UP_INSERT | DBPROPVAL_UP_DELETE);	propset.AddProperty(DBPROP_SERVERDATAONINSERT,true);	StateIn rowValue_StateIn;	rs.CreateAccessor(2, &rowValue_StateIn, sizeof(rowValue_StateIn));	rs.AddBindEntry(1, DBTYPE_I4,sizeof(rowValue_StateIn.uiMessageKey),           &rowValue_StateIn.uiMessageKey,NULL,&dwStatus);	rs.AddBindEntry(2, DBTYPE_STR, sizeof(rowValue_StateIn.pszMessage),          &rowValue_StateIn.pszMessage,NULL);	TCHAR * m_strQuery = _T("select * from statemin1");	hr = rs.Create(m_session,m_strQuery);	hr = rs.Open(&propset);		dwStatus = DBSTATUS_S_IGNORE;	TCHAR szInsStr[50];	strcpy(szInsStr,"test1");	strcpy(rowValue_StateIn.pszMessage, szInsStr);	hr = rs.Insert(0,1);	for(int j = 0;j < 20000;j++)	{			strcpy(rowValue_StateIn.pszMessage, szInsStr);		hr = rs.Insert(0,1);	}   	return S_OK;}
  3. パフォーマンス モニタを起動して、コードが実行されている間、そのプロセスの [Private Bytes] カウンタを監視します。
関連情報を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください。
301953 SQLOLEDB: Unenlisting from Active Transaction Against SQL Server 7.0 Causes Hang and Drain Abort
関連情報
この資料は米国 Microsoft Corporation から提供されている Knowledge Base の Article ID 302995 (最終更新日 2001-12-05) を基に作成したものです。

この資料に含まれているサンプル コード/プログラムは英語版を前提に書かれたものをありのままに記述しており、日本語環境での動作は確認されておりません。

プロパティ

文書番号:302995 - 最終更新日: 02/26/2014 20:53:13 - リビジョン: 2.2

  • Microsoft Data Access Components 2.1
  • Microsoft Data Access Components 2.1 Service Pack 2
  • Microsoft Data Access Components 2.1 Service Pack 1
  • Microsoft Data Access Components 2.1 Service Pack 2
  • Microsoft Data Access Components 2.5
  • Microsoft Data Access Components 2.5 Service Pack 1
  • Microsoft Data Access Components 2.5 Service Pack 2
  • Microsoft Data Access Components 2.5 Service Pack 3
  • Microsoft Data Access Components 2.6
  • kbnosurvey kbarchive kbbug kbfix kbsqlserv2000presp2fix KB302995
フィードバック