我的问题是这样的,如何使用oci获取一个类型为long,和clob字段的大小和内容,我发现用OCIAttrGet( ...OCI_ATTR_DATA_SIZE,...)来获取字段大小的时候有个问题,就是获取的是字段定义的大小并不是内容的大小,比如我得字段是varchar(32)那就算我只存放了3个byte我获取的也是32个字节长,更麻烦的是,当字段类行为long和clob的时候,竟然获取不到实际的长度,由于我们的表中用long保存文本,很大的文本可能要2M左右,所以我现在无法获取这类字段的大小也就无法分配空间
请问这是怎么回事啊,应该怎么解决阿,专家帮着给看看多谢了
下面是具体的问题的描述,耽误各位时间了谢了。
具体问题描述:
我在编写一个oracle接口库,能够执行一个动态的sql语句,比如 select * from sql_driver_test 这样的语句
我找了了一个select_query函数,他的流程基本是这样的
select_query()
{
OCIStmtPrepare ()...;
/*执行sql*/
OCIStmtExecute() ..;
/*获取字段数*/
OCIAttrGet (queryHandle,
(ub4)OCI_HTYPE_STMT,
(dvoid *) &count,
(ub4 *) 0,
(ub4)OCI_ATTR_PARAM_COUNT,
errHandle))
rowdata=(char **)malloc(sizeof(char *) * (colcount+1) );
indicators = (sb2 *) malloc(sizeof(sb2) * (colcount+1) );
/* 遍历所有字段 */
for (y=1; y <= colcount; y++)
{
OCIParamGet(queryHandle, OCI_HTYPE_STMT,
errHandle,
(dvoid **)¶m,
(ub4) y);
/* 获取当前字段的数据类型 */
OCIAttrGet((dvoid*)param, OCI_DTYPE_PARAM,
(dvoid*)&dtype, (ub4*)0, OCI_ATTR_DATA_TYPE,
errHandle);
/*设置默认字段大小 ---32*/
dsize=MAX_DATASTR_LEN;
switch(dtype)
{
#ifdef SQLT_AFC
case SQLT_AFC: /* ansii fixed char */
#endif
#ifdef SQLT_AFV
case SQLT_AFV: /* ansii var char */
#endif
case SQLT_VCS: /* var char */
case SQLT_CHR: /* char */
case SQLT_STR: /* string */
/* 问题就在这里,我后来加上去的 */
case SQLT_LNG:
/*这个也是我后来加上去的 当内容不超过4000可以工作*/
case SQLT_CLOB:
OCIAttrGet((dvoid*)param, (ub4) OCI_DTYPE_PARAM,
(dvoid*) &dsize, (ub4 *)0, (ub4) OCI_ATTR_DATA_SIZE,
errHandle);
rowdata[y-1]=malloc(dsize+1);
if (! (rowdata[y-1]) )
{
rc = SQL_SYS_ERROR;
goto sel_query_out;
}
break;
case SQLT_DAT:
case SQLT_INT:
case SQLT_UIN:
case SQLT_FLT:
case SQLT_PDN:
case SQLT_BIN:
case SQLT_NUM:
rowdata[y-1]=malloc(dsize+1);
if (! (rowdata[y-1]) )
{
rc = SQL_SYS_ERROR;
goto sel_query_out;
}
break;
default:
dsize=0;
rowdata[y-1]=NULL;
break;
}
indicators[y-1] = 0;
/* define, 所有数据类型都使用类型 sqlt_str*/
x=OCIDefineByPos(queryHandle,
&define,
errHandle,
y,
(ub1 *) rowdata[y-1],
dsize+1,
SQLT_STR,
&indicators[y-1],
(dvoid *) 0,
(dvoid *) 0,
OCI_DEFAULT);
}
}
现在问题就在于case的这个分支
原来的程序并不对 SQLT_LNG (long)类型作判断,原因就不说了
现在我们的数据库里面有的表可能使用了long来保存长文本,但是我发现这样直接加上对此类型的判断并不奏效,主要是
OCIAttrGet((dvoid*)param, (ub4) OCI_DTYPE_PARAM,
(dvoid*) &dsize, (ub4 *)0, (ub4) OCI_ATTR_DATA_SIZE,
errHandle);
调用后dsize 为0, 可实际上那个long字段里面有内容
但是似乎娶不到字段大小
我想这个可能跟建立表时没有指定long的长度有关系,因为我发现对于一个varchar2的字段,假设我指定 name字段类型为varchar2,长度32,那么即使我只存储了一个3个byte的名字,那么调用上面的OciattrGet返回的长度也是32,似乎此函数只能返回字段建立时的类型不能返回实际数据大小,这是怎么回事呢?
后来我尝试了把long字段改称clob字段,然后加上case判断语句,然后调用OCIAttrGet,同样的流程就可以了,不过可笑的字段内容不能超过4000,超过了还是不行,我正在看长达1258页OCI的编程指南,头都晕了,见笑
写得比较乱,有经验的哥们帮帮忙吧,有经验的兄弟帮帮忙,多谢。
__________________________________