C++读取Oracle中clob类型使用otl_lob_stream,发现读取的数据只是覆盖原来的数据, 原来的数据还保留,怎么在读取前清空呢?:报错
代码如下所示:
otl_stream s; otl_lob_stream lob; otl_long_string lstrCont(1024*1024);
//下面是构建成Sql语句,查询id大于某个值的100行中id,url,content三列的值 CString strSql; strSql.Format( "SELECT id, url, CONTENT FROM PUBOPANALYSIS where id > %d And RowNum < 100", m_Pid);
try { s.set_lob_stream_mode(true);
s.open(1, strSql.GetBuffer(), g_otlOra); strSql.ReleaseBuffer();
while (!s.eof()) { WebPage wp;
ZeroMemory(chUrl, 1024*2); //这里清空获取Url的值的变量,如果这里有个清空lob的值的函数或者方法,我想问题应该可以解决
s>>wp.nId>>chUrl>>lob;
wp.strUrl = chUrl;
while (!lob.eof()) //循环获取Content的内容
{
lob>>lstrCont;
strMsg.Format( "%s", lstrCont.v );
wp.strCont += strMsg;
}
lob.close();
arr.Add(wp); //这里把查询下来的数据拼成一个数组(或链表)
}
出现的情况描述如下:
现在我需要循环读出查询出来的每一行数据,但是发现问题是这样的,问题出现在Content的读取上,举个例子:
假如读取出来的第一行的Content是“1234567890”,我取出完毕;Why C++######回复 @宏哥 : 好吧...可是我早已决定要解决这个问题了。######回复 @meloyi : 换语言######回复 @宏哥 : 晕....还是帮我解决一下我上面提到的问题吧。######回复 @meloyi : 是啊,, 生命没有必要被语言浪费,连接,然后查询,,那么简单的东西, 为什么要复杂了######回复 @宏哥 : 嗯 好######这种程序一般有一个属性标识数据长度的,而不是普通的以\0结尾。建议往这个方向找下API文档。你这个程序之所以能跑是因为前面的zeromemory刚好把所有数据初始化成\0了,如果你全部初始化成比如?,估计你的程序会报错。######我找了,有,但是不是我想要的,有用于算出整个数据长度,但是没有找到算当前接收的长度的方法。上面的zeromemory只是初始化了用于接收Url的变量的值,如果初始化别的值也有可能会出现我上面提到的问题,是很有可能会报错,所以清零。由于没有清空用于接收Content的方法,所以出现了上面提到的问题,如果可以找到一个方法初始化这个lob就好了,只是我一直没有找到,所以来求助。######求助啊啊啊######如果没有什么特别好的方法,就把读出来的值记录下来,然后手动清空呗,这有啥纠结的,otl本来就不是十全十美的######回复 @刘大神 : 谢谢啊。这个链接中不包含我想要的内容,链接中有提到如何读取数据记录。我上面写的代码就是这样做的。Oracle数据库中的数据是varchar类型,那么char接收是没有问题的,并且zeromemory就可以解决我上面提到的问题,而我现在想要查询的Content这个列在Oracle中是Clob类型,它不能用char接收,接收会报错,这里就是我遇到的问题。######回复 @刘大神 : 嗯 好######回复 @meloyi : 来,照着这个做,http://blog.csdn.net/heangel/article/details/7212260######回复 @刘大神 : 谢谢啊,我第一次用otl,还有很多不懂的问题,找出这个 bug都找了半天时间。之前数据库用的是sqlserver,现在改成了Oracle。不太懂otl,所以没有找到合适方法。例子也找了,但是没有找到我想要的,所以发帖求助。######回复 @meloyi : otl不是提供了N多个例子么?你看看呗,我记得没有你这么复杂啊,就是一个变量清空的过程呀,我用过mysql的那个接口,都没这么复杂######
现在我已经把
otl_lob_stream lob;
的定义放在了循环体里面了,但是还是一样的效果,说明问题是在
otl_stream s;这里。
otl_stream s; //otl_lob_stream lob; otl_long_string lstrCont(1024*1024); CString strSql; strSql.Format( "SELECT id, url, CONTENT FROM PUBOPANALYSIS where id > %d And RowNum < 100", m_Pid); int offline = 1; try { s.set_lob_stream_mode(true); s.open(1, strSql.GetBuffer(), g_otlOra ); strSql.ReleaseBuffer(); while (!s.eof()) { WebPage wp; ZeroMemory(chUrl, 1024*2); otl_lob_stream lob; //放在这里 s>>wp.nId>>chUrl>>lob; wp.strUrl = chUrl; while (!lob.eof()) { lob>>lstrCont; strMsg.Format( "%s", lstrCont.v ); wp.strCont += strMsg; } lob.close(); arr.Add(wp); iRecNum++; } }
感觉occi并不好用,我觉得还不如用ocilib
http://www.oschina.net/p/ocilib
######嗯 谢谢######otl_stream s; otl_lob_stream lob; //otl_long_string lstrCont(1024*1024); //注释掉了这一行 CString strSql; strSql.Format( "SELECT id, url, CONTENT FROM PUBOPANALYSIS where id > %d And RowNum < 200", m_Pid); int offline = 1; WirteLog( m_currPath + _T("\\Process.log"), strSql ); try { s.set_lob_stream_mode(true); s.open(1, strSql.GetBuffer(), g_otlOra); strSql.ReleaseBuffer(); while (!s.eof()) { WebPage wp; ZeroMemory(chUrl, 1024*2); s>>wp.nId>>chUrl>>lob; otl_long_string lstrCont(1024*1024); //最终我把这个变量声明放在了这里 wp.strUrl = chUrl; while (!lob.eof()) { lob>>lstrCont; strMsg.Format( "%s", lstrCont.v ); wp.strCont += strMsg; } lob.close(); arr.Add(wp); iRecNum++; //strMsg.Format( "nId = %d, Read information succeed, content = \r\n%s", wp.nId, wp.strCont ); //WirteLog( m_currPath + _T("\\Process.log"), strMsg ); } }
如上图,我把下面的这个变量的声明换了一个位置,放在了循环里面,最后解决了我在上面提到的问题:
otl_long_string lstrCont(1024*1024);
虽然也可以解决问题,但是这样的话就每次读取数据都需要重新申请内存空间,效率会降低。如果能够找到初始化的方法就最好了
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。