我用 VC 读写 ORACLE 里的 CLOB 数据时为什么会出错?

PatrickGamp 2001-10-09 10:25:01
请大家看下面的代码有什么问题:
/// 把 Clob 类型的字段的值读出来,放到 buffer 里,返回其长度 ///
int ReadClobToBuffer(const OClob* pOClob,
unsigned char *buffer)
{
unsigned char *buffer_ptr;
int total_len;//实际上读取的字节数的总和,返回值
unsigned long size;
unsigned long optchunk;
unsigned int bufsize;
short status;
unsigned long real_size_read;//实际上读取的字节数(每一次)

total_len = 0;
buffer_ptr = buffer;
try
{
if(pOClob->IsNull())
return 0;
size = pOClob->GetSize();//得到 size
optchunk = pOClob->GetOptimumChunkSize();//得到最优的 size
bufsize = ((int)(32768/optchunk)) * optchunk;//确定每次读的 size
if (bufsize > size)//每次读的 size 不能大于该 LOB 的 size
bufsize = size;
pOClob->EnableStreaming(size);//必须使 LOB 成为 streaming 的
status = OLOB_NEED_DATA;//初始化状态为"有数据要输出"
while(status == OLOB_NEED_DATA)
{
real_size_read = pOClob->Read(&status, buffer_ptr, bufsize, 0);
buffer_ptr += real_size_read;
total_len += real_size_read;
}
pOClob->DisableStreaming(); //恢复 LOB 为 non_streaming
}
catch(OException o_except)
{
char error_string[640];
sprintf(error_string,"ORACLE 在 %s 函数中发生错误,错误原因是:\r\n%s",
o_except.GetFailedMethodName(),o_except.GetErrorText());
//AfxMessageBox(error_string);
}
return total_len;
}


/// 写数据到 Clob 里,请注意,在此之前一定要用 AddNewRecord/StartEdit ///
/// 使该字段里的 clob 数据或空,并且调用了 Update ,使之为空 ///
bool WriteBufferToClob(unsigned char* buffer,
unsigned long buffer_size,
OClob* pOClob)
{
unsigned long optchunk;
unsigned int bufsize,size_to_write;
unsigned char piecetype;
unsigned long totalwritten;
unsigned char* buffer_ptr;
int flag;

flag = 0;
totalwritten = 0;//已经写了的字节数
buffer_ptr = buffer;
try
{
optchunk = pOClob->GetOptimumChunkSize();//得到最优的 size
bufsize = ((int)(32768/optchunk)) * optchunk;//确定每次读的 size
if (buffer_size <= bufsize)//只够写一次的
piecetype = OLOB_ONE_PIECE;
else//需要写多次时,必须使 LOB 成为 streaming 的
{
piecetype = OLOB_FIRST_PIECE;//设置为第一次
pOClob->EnableStreaming(buffer_size);
flag = 1;
}
while(totalwritten < buffer_size)
{
if(buffer_size - totalwritten >= bufsize)
size_to_write = bufsize;
else
size_to_write = buffer_size - totalwritten;
pOClob->Write(buffer_ptr, size_to_write, piecetype , 0);
totalwritten += size_to_write;
if (buffer_size - totalwritten <= bufsize)
piecetype = OLOB_LAST_PIECE;//最后一次写了
else
piecetype = OLOB_NEXT_PIECE;//下一次的
}
if(flag == 1)
pOClob->DisableStreaming();//恢复 LOB 为 non_streaming

}
catch(OException o_except)
{
char error_string[640];
sprintf(error_string,"ORACLE 在 %s 函数中发生错误,错误原因是:\r\n%s",
o_except.GetFailedMethodName(),o_except.GetErrorText());
//AfxMessageBox(error_string);
return false;
}
return true;
}

在写 clob 时我先将其清空
oval.SetEmpty();
OraDynaset.SetFieldValue(fieldname,oval);//先清空 Clob 里的东西
if(OraDynaset.Update() != OSUCCESS)
return -109;
OraDynaset.StartEdit();//再准备往 Clob 里写东西
OraField = OraDynaset.GetField(fieldname);
OraField.GetValue(&oclob);
if(!WriteBufferToClob((unsigned char *)&sval[0],len,&oclob))
return -112;

我觉得完全按照 ORACLE 里的例子来写的,为什么总是出错? 它不报错,但是读出来时总是双工错误,谁能帮我,我给分信誉良好.
...全文
99 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
PatrickGamp 2001-10-09
  • 打赏
  • 举报
回复
在我每次写了之后忘记挪动指针了,我怎么犯这种错误?
但是当我改正这一点之后,它还是有问题,除了第一次写了很多字节,以后的每一次都只写一个字节,而且读出来还是错误
Jneu 2001-10-09
  • 打赏
  • 举报
回复
up
Jneu 2001-10-09
  • 打赏
  • 举报
回复
gz
PatrickGamp 2001-10-09
  • 打赏
  • 举报
回复
终于调试出来了,原来在写 clob 后有一个 Update 和一个 StartEdit 动作,在 ORACLE 的规则里,在这两个函数中必须插入一个 Refresh 动作,否则 Update 之后的 lock 会失效.
可气的是,ORACLE 的帮助里竟然把这个 Refresh 函数给落了,害得我调试了两天了。这几十分只能给我自己了,我也够辛苦的了.

2,596

社区成员

发帖
与我相关
我的任务
社区描述
Sybase相关技术讨论区
社区管理员
  • Sybase社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧