社区
数据库
帖子详情
有什么办法能解决使用ADO访问ORACLE数据库的CLOB字段的有内存泄漏问题?
wuchunzhong
2004-01-06 02:34:27
现在我使用一个简单的SQL语句的某张表的数据,但是这张表中有CLOB字段,这时会发现此应用程序有内存泄漏,不知有没有什么好办法可以解决!
...全文
112
14
打赏
收藏
有什么办法能解决使用ADO访问ORACLE数据库的CLOB字段的有内存泄漏问题?
现在我使用一个简单的SQL语句的某张表的数据,但是这张表中有CLOB字段,这时会发现此应用程序有内存泄漏,不知有没有什么好办法可以解决!
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
14 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
wuchunzhong
2004-01-12
打赏
举报
回复
呵呵,我自己来UP一下!希望大家能到这儿来发表自己的看法。谢谢。
wuchunzhong
2004-01-09
打赏
举报
回复
有什么办法能让只读的Recordset变成可以保存数据的Recordset,各种方式都可以。但是使用_CommandPtr的Execute方法查询得到的Recordset的信息不全!
wuchunzhong
2004-01-08
打赏
举报
回复
现在的问题不是在于怎样在Recordset中怎样取数据,而是采用客户端游标的情况下使用Recordset查询数据就有内存泄漏。当然ORACLE的解决办法是提示取数的绑定变量地方申请一个缓冲区就可以了,但是采用命令的方式使用Recordset的OPEN方法好像设置的参数不起作用,只有采用_CommandPtr的Execute方法设置的参数才起作用。但是ado好像又没有任何地方提示需要怎么做!
najzni
2004-01-08
打赏
举报
回复
一些特殊字段,比如存储的图片信息,一般用GetChunk()来取,用AppendChunk()来存。
wuchunzhong
2004-01-08
打赏
举报
回复
至于产生内存泄漏的地方不是别的地方,正是产生Recordset的地方。对于Oracle的OleDB说的是需要指定使用的SQL语句中有LOB字段,并指定绑定变量需要分配多大的空间,这样才是问题的解决的真正办法,但是一旦使用命令参数就出现上面的问题。注如果使用服务器游标是没有内存泄漏的但是不满足我使用的环境,因为我是在专用的COM+数据库连接池中使用,所以必须把无连接的Recordset返回给调用者。
wuchunzhong
2004-01-08
打赏
举报
回复
我也遇到一个问题使用如下办法取的Recordset不会有内存泄漏但是此时的Recordset是只读的
STDMETHODIMP GetRecordset(BSTR bstrSQL, _Recordset **ppRs)
{
HRESULT hr;
VARIANT var;
long lCount = 0;
_CommandPtr spAdoCmd = NULL;
_ParameterPtr spAdoClob = NULL;
_RecordsetPtr spAdoRs = NULL;
VariantInit(&var);
try
{
m_spAdoCon->PutCursorLocation(adUseClient);
hr = spAdoCmd.CreateInstance(__uuidof(Command));
if(FAILED(hr)) return hr;
spAdoCmd->ActiveConnection = m_spAdoCon;
spAdoClob = spAdoCmd->CreateParameter(L"prCLOB",adLongVarChar,adParamOutput,100000);
hr = spAdoCmd->Parameters->Append(spAdoClob);
spAdoCmd->Properties->GetItem(L"SPPrmsLOB")->Value = 1L;
spAdoCmd->CommandText = bstrSQL;
spAdoRs = spAdoCmd->Execute(&var,NULL,adCmdText);
var.vt = VT_DISPATCH;
var.pdispVal = NULL;
spAdoRs->PutActiveConnection(var);
*ppRs = spAdoRs.Detach();
VariantClear(&var);
}
catch(_com_error e)
{
//异常处理
}
return S_OK;
}
用如下的办法得到的Recordset是可写的,但是会产生内存泄漏
STDMETHODIMP GetRecordset(BSTR bstrSQL, _Recordset **ppRs)
{
HRESULT hr;
VARIANT var;
long lCount = 0;
_CommandPtr spAdoCmd = NULL;
_ParameterPtr spAdoClob = NULL;
_RecordsetPtr spAdoRs = NULL;
VariantInit(&var);
try
{
m_spAdoCon->PutCursorLocation(adUseClient);
hr = spAdoCmd.CreateInstance(__uuidof(Command));
if(FAILED(hr)) return hr;
spAdoCmd->ActiveConnection = m_spAdoCon;
spAdoClob = spAdoCmd->CreateParameter(L"prCLOB",adLongVarChar,adParamOutput,100000);
hr = spAdoCmd->Parameters->Append(spAdoClob);
spAdoCmd->Properties->GetItem(L"SPPrmsLOB")->Value = 1L;
spAdoCmd->CommandText = bstrSQL;
hr = spAdoRs.CreateInstance(__uuidof(Recordset));
if(FAILED(hr)) return hr;
spAdoRs->PutCursorLocation(adUseClientBatch);
spAdoRs->Open((IDispatch *)spAdoCmd, vtMissing, adOpenStatic, adLockBatchOptimistic, -1);
var.vt = VT_DISPATCH;
var.pdispVal = NULL;
spAdoRs->PutActiveConnection(var);
*ppRs = spAdoRs.Detach();
VariantClear(&var);
}
catch(_com_error e)
{
//异常处理
}
return S_OK;
}
说明对于此语句只能是使用ORACLE数据库才可运行,因为有它的专用属性SPPrmsLOB及专用参数。
希望大家帮忙,至于分的问题不是问题。
wuchunzhong
2004-01-07
打赏
举报
回复
经过一段时间的仔细琢磨终于找到了解决办法。就是采用_CommandPtr接口的Execute方法,设置一定的参数就可以不内存泄漏!但是Execute方法默认返回的结果集是悲观锁方式的,由于我的程序是放在COM+中运行的所以必须要是乐观锁批更新方式(adLockBatchOptimistic)的锁的结果集才能在客户端进行修改。所以有什么办法可以让Execute方法返回的结果集是以adLockBatchOptimistic锁的!对于采用创建一个新的结果集的方式就不用说了,因为那种方式较慢。谢谢大家的支持!
丁淇石头
2004-01-07
打赏
举报
回复
学习
arvid_gs
2004-01-06
打赏
举报
回复
ESULT hr = m_pRecordset->Open("SELECT * FROM userphoto",_variant_t((IDispatch *)theApp.m_pConnection,true),adOpenDynamic,adLockPessimistic,adCmdText);
bluebohe
2004-01-06
打赏
举报
回复
CLOB字段最好用GetChunck的方式一段一段的取
wuchunzhong
2004-01-06
打赏
举报
回复
m_spAdoCon是当前的数据库连接对象!
wuchunzhong
2004-01-06
打赏
举报
回复
我这儿就放一段访问数据库的代码吧!其中m_strSql是界面录入的SQL语句,如果SQL语句中不含CLOB字段是没有一点内存泄漏,但是只要有CLOB字段就会出现分配的类春不能完全释放 for(long i= 0;i < 10;i++)
{
CComBSTR bstrSql;
_RecordsetPtr spAdoRs;
try
{
HRESULT hr = spAdoRs.CreateInstance(__uuidof(Recordset));
if(FAILED(hr)) continue;
spAdoRs->PutCursorLocation(adUseClientBatch);
bstrSql = m_strSql;
spAdoRs->Open((BSTR)bstrSql, m_spAdoCon.GetInterfacePtr(), adOpenStatic, adLockBatchOptimistic, -1);
}
catch(_com_error e)
{
CString str,strMsg;
str = (BSTR)e.Description();
strMsg.Format(_T("错误号:%d,错误原因:%s"),e.Error(),str);
MessageBox(strMsg);
return ;
}
}
return ;
axiaowin
2004-01-06
打赏
举报
回复
内存泄漏常见的情况,
应该与数据库操作没有关系。
bluebohe
2004-01-06
打赏
举报
回复
你把程序代码放上来看一下,不是数据库问题,是代码问题
读取
oracle
数据库
中
clob
字段
的值
把
oracle
数据库
中
字段
类型为
clob
的
字段
值以字符串的形式读取出来
ORACLE
中
CLOB
字段
转String类型
ORACLE
中
CLOB
字段
转String类型
向
Oracle
数据库
插入
Clob
大段文本
解决
方法
向
Oracle
数据库
插入
Clob
大段文本
解决
方法
jdbc读写
Oracle
的
CLOB
字段
JDBC读写
Oracle
的
CLOB
字段
java读取
oracle
数据库
中
clob
字段
.txt
java读取
oracle
数据库
中
clob
字段
把
oracle
数据库
中
字段
类型为
clob
的
字段
值以字符串的形式读取出来
数据库
4,012
社区成员
39,817
社区内容
发帖
与我相关
我的任务
数据库
VC/MFC 数据库
复制链接
扫一扫
分享
社区描述
VC/MFC 数据库
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章