我正在尝试使用Pro * C从游标中获取数组。
这样的事情:
struct array {
char key[10]];
char name[32];
};
struct array rows[250];
// Open cursor...
EXEC SQL FETCH my_cursor INTO :rows;
这样可行,但字段不是以空值终止的。我想这是因为我通常会使用:
EXEC SQL VAR key IS STRING(11);
EXEC SQL VAR name IS STRING(33);
但这似乎不适用于数组。
有谁知道如何解决这个问题?
谢谢!
答案 0 :(得分:2)
这些值被视为(Oracle)CHAR
,因为无法确定长度。由于它是fixed size,因此用空格填充值是正常的。
使用虚拟表:
create table t42 (key varchar2(10), name varchar2(32));
insert into t42 values ('abc','A B C');
insert into t42 values ('def','D E F');
commit;
此代码:
#include <string.h>
#include <stdio.h>
exec sql include sqlca.h;
int main(int argc, char **argv)
{
VARCHAR v_userid[15];
VARCHAR v_passwd[15];
struct array {
char key[10];
char name[32];
};
struct array rows[2];
strcpy(v_userid.arr, "user");
v_userid.len = 5;
strcpy(v_passwd.arr, "password");
v_passwd.len = 8;
exec sql connect :v_userid identified by :v_passwd;
if (sqlca.sqlcode != 0)
{
printf("ORA%d: %s\n", sqlca.sqlcode, sqlca.sqlerrm);
return(1);
}
memset(rows, '\0', sizeof(rows));
EXEC SQL DECLARE cur CURSOR FOR select * from t42;
EXEC SQL OPEN cur;
EXEC SQL FETCH cur INTO :rows;
printf("%d\n", sqlca.sqlcode);
printf("<%s><%s>\n", rows[0].key, rows[0].name);
printf("<%s><%s>\n", rows[1].key, rows[1].name);
EXEC SQL CLOSE cur;
}
...显示您描述的相同行为:
0
<abc ><A B C >
<def ><D E F >
在获取数据时,你实际上是在进行隐式cast(key as char(10))
,这会引入填充,因为它知道它会进入CHAR
而不是VARCHAR
变量。
将数组成员更改为VARCHAR
data types(包括引用.arr
成员):
#include <string.h>
#include <stdio.h>
exec sql include sqlca.h;
int main(int argc, char **argv)
{
VARCHAR v_userid[15];
VARCHAR v_passwd[15];
struct array {
VARCHAR key[10];
VARCHAR name[32];
};
struct array rows[2];
strcpy(v_userid.arr, "user");
v_userid.len = 5;
strcpy(v_passwd.arr, "password");
v_passwd.len = 8;
exec sql connect :v_userid identified by :v_passwd;
if (sqlca.sqlcode != 0)
{
printf("ORA%d: %s\n", sqlca.sqlcode, sqlca.sqlerrm);
return(1);
}
memset(rows, '\0', sizeof(rows));
EXEC SQL DECLARE cur CURSOR FOR select * from t42;
EXEC SQL OPEN cur;
EXEC SQL FETCH cur INTO :rows;
printf("%d\n", sqlca.sqlcode);
printf("<%s><%s>\n", rows[0].key.arr, rows[0].name.arr);
printf("<%s><%s>\n", rows[1].key.arr, rows[1].name.arr);
EXEC SQL CLOSE cur;
}
...让它按预期工作:
0
<abc><A B C>
<def><D E F>
当然有一个错误(好吧,至少有一个!)我故意留下了。如果我的数据库字段是10和32个字符,那么VARCHAR
元素的大小 - 或原始的char
元素 - 需要大一个字节来保存终止空值 - 这是当然基本的C东西,所以你的真实列完全可能分别是9和31个字符(尽管你的EXEC SQL VAR
示例表明没有)。我有这样的组合,如果我:
insert into t42 values ('1234567890','12345678901234567890123456789012');
...然后第三行显示为:
<1234567890 ><12345678901234567890123456789012@>
...因为它正在读取已分配的空间。当然,如果我制作结构VARCHAR key[11]; VARCHAR name[33];
,则按预期工作。