c语言进阶-利用c语言解构oracle底层数据(不开库)-oracle列类型存储格式解析

6 篇文章 0 订阅
4 篇文章 0 订阅

人的大脑和肢体一样,多用则灵,不用则废。——茅以升 

    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;
}

    其他用得少的类型算法暂不贴,有兴趣的可以自己实现试试。

三、总结

    表列数据存储算法实现后,我们只要获取表列数据存储位置,拿出存储的数据,然后通过转换算法即可获取表列数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值