人的大脑和肢体一样,多用则灵,不用则废。——茅以升
oracle表列类型有很多种,常见的有:char,varchar2,number,date等。要利用c语言读取oracle数据块中的数据,除了从块中拿到表列的数据,需要根据列类型存储算法进行解构。
一,oracle列内部代码
oracle每个列的类型都有一个内部代码。oracle通过表col$中的type#字段中,存储了数据库中每个表的各个列的内部代码,通过这个代码,可以知道每个表每个列的类型是什么。
#define O_TYPE_CHAR 96
#define O_TYPE_VARHCAR2 1
#define O_TYPE_NUMBER 2
#define O_TYPE_LONG 8
#define O_TYPE_RAW 23
#define O_TYPE_LONG_RAW 24
#define O_TYPE_DATE 12
#define O_TYPE_TIME 178
#define O_TYPE_TIME_ZONE 179
#define O_TYPE_TIMESTAMP 180
#define O_TYPE_TIMESTAMP_ZONE 181
#define O_TYPE_TIMESTAMP_LOCAL_ZONE 231
#define O_TYPE_INTERNAL_YEAR_MONTH 182
#define O_TYPE_INTERNAL_DAY_SECOND 183
#define O_TYPE_SYSDATE 13
#define O_TYPE_UROWID 208
二,类型算法
oracle中char和varchar2都是字符对应字符码(需考虑字符集)直接存储,不需要转换。其他一些类型都需要进行转换,下面列出基本算法;
number类型算法:
double blockHexToNumber(const unsigned char *hs, size_t len){
if(len == 1)
return 0;
sb1 ext;
double value = 0.0f;
// printf("the value of hex is %d\n", *hs);
if(*hs > 128){
ext = (*hs - O_NUMBER_PSTIV_BASE);
for(int i=1;i<len;i++){
value += ((hs[i]-1)*pow(100,(ext-i+1)));
}
}else{
ext = (O_NUMBER_NETIV_BASE - *hs);
for(int i=1;i<len-1;i++){
value += ((O_NUMBER_NETIV_MO - hs[i])*pow(100,(ext-i+1)));
}
value *= (-1);
}
return value;
}
char和varchar方法:
char *blockHextoString(const unsigned char *hs, size_t len){
unsigned char *dstr = malloc(sizeof(unsigned char)*(len+1));
memcpy(dstr, hs, len);
dstr[len] = '\0';
return dstr;
}
date类型算法:
static void decNumToChar(char *s, char input, size_t offset){
if(input < 10){
s[offset] = '0';
s[offset+1] = '0' + input;
} else{
s[offset] = '0' + (input/10);
s[offset+1] = '0' + (input%10);
}
}
char *blockHextoDate(const unsigned char *hs, size_t len){
char *dstr = malloc(sizeof(char)*20);
unsigned char s = hs[0] - 100;
decNumToChar(dstr, s, 0);
s = hs[1] - 100;
decNumToChar(dstr, s, 2);
dstr[4] = '/';
s = hs[2];
decNumToChar(dstr, s, 5);
dstr[7] = '/';
s = hs[3];
decNumToChar(dstr, s, 8);
dstr[10] = ' ';
s = hs[4] - 1;
decNumToChar(dstr, s, 11);
dstr[13] = ':';
s = hs[5] - 1;
decNumToChar(dstr, s, 14);
dstr[16] = ':';
s = hs[6] - 1;
decNumToChar(dstr, s, 17);
dstr[19] = '\0';
return dstr;
}
其他用得少的类型算法暂不贴,有兴趣的可以自己实现试试。
三、总结
表列数据存储算法实现后,我们只要获取表列数据存储位置,拿出存储的数据,然后通过转换算法即可获取表列数据。