Chinaunix首页 | 论坛 | 博客
  • 博客访问: 61678
  • 博文数量: 24
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 215
  • 用 户 组: 普通用户
  • 注册时间: 2015-02-10 09:58
个人简介

专业提供linux应用软件开发、oracle数据库底层开发,服务器开发及相关技术支持服务

文章分类

全部博文(24)

文章存档

2015年(24)

我的朋友

分类: 数据库开发技术

2015-02-28 10:20:46

项目开发中,需要从数据库查询数据,在不使用数据库库函数的情况下对获取的数据解析,
这时就可以对查询的SQL语句操作,使其要查询的每一项通过连接符连接在一起成为一项查询
这时通过查询获取的数据就是一列的数据--一个字符串,再对字符串操作获取对应的每一项数据。
在编程实现中,可以把对SQL语句的操作看着是对字符串的操作,获取的结果也是看做字符串解析。
下面是简单实现,
环境:linux,oracle数据库,OCILIB库


点击(此处)折叠或打开

  1. 代码实现:

  2. /*存放每一行数据的结构体*/
  3. typedef struct _resultdata
  4. {
  5.     int num;
  6.     int row_len;
  7.     SB1 *row_data;
  8.     struct _resultdata *next;
  9. }ResultData;

  10. /***********************************************************
  11.  *function:rs_link_insert
  12.  *description:
  13.  * 查询数据链表插入,将新的查询数据放进链表中
  14.  *input: head:链表头
  15.  * pi: 将要插进的新结点
  16.  *
  17.  *output: ResultData * :返回ResultData *指针,一般是链表
  18.  *头结点
  19.  * ********************************************************/
  20.  ResultData *rs_link_insert(ResultData *head,ResultData *pi)
  21. {
  22.     ResultData *pb = NULL;

  23.     pb = head;
  24.     //链表为空时,创建链表
  25.     if(NULL == pb)
  26.     {
  27.         pb = pi;
  28.         pi->next = NULL;
  29.         head = pb;
  30.         
  31.         //rs_tail = pi;
  32.         return head;
  33.     }
  34.     //不为空时,找到尾结点,并判断是否为空,为空将新结点
  35.     //插入当前尾结点后
  36.     //然后将新节点作为尾结点
  37.     while(pb->next)
  38.     {
  39.         //pf = pb;
  40.         pb = pb->next;
  41.     }
  42.     pb->next = pi;
  43.     pi->next = NULL;
  44.     return head;
  45.     
  46. }

  47. /***********************************
  48.  *function: sql_format_deal
  49.  *description:
  50.  * 将源字符串中’,‘替换为“||chr(1)||
  51.  *input: source:源字符串
  52.  * search:格式化后的字符串
  53.  *
  54.  *output: 列值
  55.  * ********************************/
  56.  int sql_format_deal(char* csource_ext,char *cresult)
  57. {
  58.     int iwork_bgn = 0;//单词标示
  59.     int ibracket = 0;//括号标志
  60.     int icol_cnt = 1;//列值
  61.     char *csource = (char *)malloc(strlen(csource_ext) + 64);
  62.     char *csrc = csource;
  63.     char *cres = cresult;

  64.     strcpy(csource, csource_ext);
  65.     for(iwork_bgn=1,ibracket=0;*csrc;csrc++)
  66.     {
  67.         //如果到了from处,则不再替换
  68.         if((!strncasecmp(csrc,"from",4))&&iwork_bgn)
  69.         {
  70.             if(csrc[4]==0 || strchr(" \t\r\n",csrc[4]))
  71.             {
  72.                 break;
  73.             }
  74.         }

  75.         //将csrc中‘,’替换为“||chr(1)||,注:括号内不处理
  76.         if(!ibracket && *csrc == ',')
  77.         {
  78.             // 一个逗号则替换为||chr(1)||,两个逗号作为一个逗号(说明要单作为1列处理)
  79.             if(csrc[1]==',')
  80.             {
  81.                 // 保存当前逗号,跳过pi[1]的逗号
  82.                 *cres++ = *csrc++;
  83.                 icol_cnt++;
  84.             }
  85.             else
  86.             {
  87.                 //strcpy(cres,"||chr(1)||");
  88.                 strcpy(cres,"||chr(1)||");
  89.                 cres += strlen(cres);//"||chr(1)||"的长度
  90.             }
  91.         }
  92.         else
  93.         {
  94.             *cres++ = *csrc;

  95.             // 判断是否一个词的开始
  96.             iwork_bgn = strchr(" \t\r\n",*csrc)?1:0;
  97.             // 判断是否在括号内
  98.             if('(' == *csrc)
  99.             {
  100.                 ibracket++;

  101.             }
  102.             if(')' == *csrc)
  103.             {
  104.                 ibracket--;
  105.             }
  106.         }


  107.     }
  108.     // from后面的内容全部拷贝
  109.     for(;*csrc;csrc++)
  110.     {
  111.         *cres++ = *csrc;
  112.     }

  113.     *cres = '\0';

  114.     FZS_FREE(csource);
  115.     return icol_cnt;
  116. }
  117. /***********************************
  118.  *function: db_select_data
  119.  *description:
  120.  * 查询SQL语句,获得查询数据,将数据存放在rs_data内
  121.  *
  122.  *
  123.  *input: CN:数据路连接对象
  124.  * SQL:SQL执行语句
  125.  * *row_num:查询数据行数
  126.  * rs_data:存放查询后的数据`
  127.  *
  128.  *output: >=0:sucess <0:fail
  129.  *注意:开辟了rs_data及rs_link链表内存空间
  130.  * 同时释放了sele_data及se_link链表内存空间
  131.  * rs_data及rs_link内存空间由函数
  132.  * db_get_le_data释放
  133.  *
  134.  * 开辟了format_sql空间,并在用完后释放
  135.  * ********************************/
  136.  int db_select_data(OCI_Connection *cn, char* sql,int *row_num,ResultData **rs_data)
  137. {
  138.     OCI_Statement *st = NULL;
  139.     OCI_Resultset *rs = NULL;
  140.     int icolmn_cnt = 0;
  141.     int icnt = 0;
  142.     ResultData *pb_data = NULL;

  143.     ResultData *rs_head = NULL;
  144.     ResultData *rs_node = NULL;
  145.     int isql_len = 0;
  146.     SB1 *format_sql = NULL;
  147.     SB1 *ptemp = NULL;
  148.     SB1 *p1temp = NULL;
  149.     SB1 buf_data[MAX_ROW_LENGTH];
  150.     SB1 *pbuf_data = NULL;
  151.     int itemp1 = 0;
  152.     //char *ptmp = 0;
  153.     
  154.     //对SQL语句断言
  155.     assert(sql);
  156.     //判断数据库连接对象是否为空
  157.     if(NULL == cn)
  158.     {
  159.         zlog_error(fzs_lib_mod_log,"---no connect to oracle,please check connect");
  160.         return -1;
  161.     }

  162.     pthread_mutex_lock(&mutex_cn);

  163.     //zlog_error(fzs_lib_mod_log,"cn addr:%p",cn);
  164.     //通过数据库连接对象获得SQL语句执行对象
  165.     st = OCI_StatementCreate(cn);
  166.     if(NULL == st)
  167.     {
  168.         //printf("file:%s---line:%d---OCI_StatementCreate---fail\r\n",POS_INFO);
  169.         zlog_error(fzs_lib_mod_log,"---OCI_StatementCreate---fail");
  170.         OCI_err_handler(OCI_GetLastError());

  171.         pthread_mutex_unlock(&mutex_cn);
  172.         return -1;
  173.     }

  174.     //sql格式化后的结构
  175.     isql_len = strlen(sql)+1024;
  176.     //分配内存空间
  177.     format_sql = (SB1*)FZS_MALLOC(isql_len);
  178.     memset(format_sql,0,isql_len);

  179.     //格式化SQL语句
  180.     icolmn_cnt = sql_format_deal(sql,format_sql);//多列的话目前没有处理

  181.     //printf("file:%s---line:%d-format_sql=%s\r\n",POS_INFO,format_sql);
  182.     zlog_debug(fzs_lib_mod_log,"-format_sql=%s",format_sql);
  183.     //printf("file:%s---line:%d-icolmn_cnt=%d\r\n",POS_INFO,icolmn_cnt);
  184.     zlog_debug(fzs_lib_mod_log,"-icolmn_cnt=%d",icolmn_cnt);

  185.     //执行SQL语句
  186.     if(!OCI_ExecuteStmt(st,format_sql))// format_sql 是格式化后的语句
  187.     {
  188.         zlog_error(fzs_lib_mod_log,"-OCI_ExecuteStmt---fail");
  189.         OCI_err_handler(OCI_GetLastError());

  190.         pthread_mutex_unlock(&mutex_cn);
  191.         return -1;
  192.     }
  193.     
  194.     //获取结果集对象
  195.     zlog_debug(fzs_lib_mod_log,"-OCI_ExecuteStmt---OK!!!");
  196.     rs = OCI_GetResultset(st);
  197.     if(NULL == rs)
  198.     {
  199.         zlog_error(fzs_lib_mod_log,"OCI_ExecuteStmt---fail");
  200.         OCI_err_handler(OCI_GetLastError());

  201.         pthread_mutex_unlock(&mutex_cn);
  202.         return -1;
  203.     }

  204.     //对rs结果集中的数据处理,将rs数据存到rs_link中,并获得每行数据长度
  205.     while(OCI_FetchNext(rs))
  206.     {
  207.      icnt++;
  208.         //每次获得数据前,清空buf内数据
  209.         //printf("%s\n",OCI_GetString(rs,1));
  210.         memset(buf_data,0,MAX_ROW_LENGTH);

  211.         pbuf_data = buf_data;
  212.         for(itemp1 = 0; itemp1 < icolmn_cnt; itemp1++)
  213.         {
  214.             pbuf_data += strlen(pbuf_data);
  215.             if(itemp1 > 0)
  216.                 *pbuf_data++ = 0x01;

  217.          sprintf(pbuf_data, OCI_GetString(rs, itemp1 + 1));
  218.         }

  219.         //printf("file:%s--line:%d--buf_data=%s\r\n",POS_INFO,buf_data);
  220.         zlog_debug(fzs_lib_mod_log,"--buf_data=%s",buf_data);
  221.         //irow_len = strlen(buf_data)+1;
  222.         //printf("file:%s--line:%d--*len=%d\r\n",POS_INFO,*len);
  223.         //zlog_debug(fzs_lib_mod_log,"*len=%d",*len);
  224.         //给pb_data分配内存空间
  225.         pb_data = (ResultData*)malloc(sizeof(ResultData));
  226.         
  227.         //分配内存失败
  228.         if(pb_data == NULL)
  229.         {
  230.         
  231.             //printf("SelectData--pb_data malloc memory fail\r\n");
  232.          zlog_error(fzs_lib_mod_log,"OCI_ExecuteStmt---fail");
  233.          //释放返回集
  234.             if(rs)
  235.             {
  236.                 OCI_ReleaseResultsets(st);
  237.                 //printf("file:%s--line:%d--OCI_ReleaseResultsets(st) success\r\n",POS_INFO);
  238.             }

  239.             //清除声明
  240.             if(st)
  241.             {
  242.                 OCI_StatementFree(st);
  243.                 //printf("file:%s--line:%d--OCI_StatementFree(st) success\r\n",POS_INFO);
  244.             }

  245.             pthread_mutex_unlock(&mutex_cn);
  246.             return -1;
  247.         }

  248.         pb_data->row_data = (SB1*)malloc((strlen(buf_data)+1));
  249.         
  250.         //分配内存失败
  251.         if(pb_data->row_data == NULL)
  252.         {
  253.             //printf("SelectData--pb_data->row_data malloc memory fail\r\n");
  254.             zlog_error(fzs_lib_mod_log,"SelectData--pb_data->row_data malloc memory fail");
  255.             free(pb_data);
  256.             //释放返回集
  257.             if(rs)
  258.             {
  259.                 OCI_ReleaseResultsets(st);
  260.                 //printf("file:%s--line:%d--OCI_ReleaseResultsets(st) success\r\n",POS_INFO);
  261.             }

  262.             //清除声明
  263.             if(st)
  264.             {
  265.                 OCI_StatementFree(st);
  266.                 //printf("file:%s--line:%d--OCI_StatementFree(st) success\r\n",POS_INFO);
  267.             }

  268.             pthread_mutex_unlock(&mutex_cn);
  269.             return -1;
  270.         }

  271.         pb_data->num = icnt;
  272.         pb_data->row_len = strlen(buf_data)+1;
  273.         //数据全部Copy过来,不是地址赋值过来
  274.         memcpy(pb_data->row_data,buf_data,strlen(buf_data)+1);//sizeof(rs)==4,forever
  275.         pb_data->row_data[strlen(buf_data)] = '\0';
  276.         //将每一行数据作为一个结点存放在链表中
  277.         //printf("file:%s--line:%d--pb_data->row_data=%s\r\n",POS_INFO,pb_data->row_data);
  278.         zlog_debug(fzs_lib_mod_log,"--pb_data->row_data=%s",pb_data->row_data);
  279.         rs_head = rs_link_insert(rs_head,pb_data);
  280.     }

  281.     //总行数
  282.     *row_num = icnt;

  283.     *rs_data = rs_head;
  284.     //将rs_head指向空指针
  285.     rs_head = NULL;
  286.         
  287.     //rs_link_print(*rs_data);
  288.  
  289.     //将每行数据内的0x1替换为0x0
  290.     for(rs_node=*rs_data;rs_node;rs_node=rs_node->next)
  291.     {
  292.         for(ptemp = rs_node->row_data,p1temp = ptemp+rs_node->row_len;ptemp < p1temp;ptemp++)
  293.         {
  294.             
  295.             if(1 == *ptemp)
  296.             {
  297.                // printf("file:%s--line:%d--p=%c\r\n",POS_INFO,*p);
  298.               // zlog_debug(fzs_lib_mod_log,"--p=%c",*p);
  299.                 *ptemp = 0;
  300.                // printf("file:%s--line:%d--p=%c\r\n",POS_INFO,*p);
  301.               // zlog_debug(fzs_lib_mod_log,"--p=%c",*p);
  302.             }
  303.         }

  304.         //printf("file:%s--line:%d--rs_node->row_data=%s\r\n",POS_INFO,rs_node->row_data);
  305.         zlog_debug(fzs_lib_mod_log,"--rs_node->row_data=%s",rs_node->row_data);
  306.     }

  307.     //rs_link_print(*rs_data);
  308.     //释放format_sql内存空间
  309.     free(format_sql);

  310.     //释放返回集
  311.     if(rs)
  312.     {
  313.         OCI_ReleaseResultsets(st);
  314.         //printf("file:%s--line:%d--OCI_ReleaseResultsets(st) success\r\n",POS_INFO);
  315.     }
  316.     //清除声明
  317.     if(st)
  318.     {
  319.         OCI_StatementFree(st);
  320.         //printf("file:%s--line:%d--OCI_StatementFree(st) success\r\n",POS_INFO);
  321.     }

  322.     #ifdef SWITCH_LOG
  323.     if(1 == db_en_chs_flag)
  324.     {
  325.         zlog_info(fzs_lib_mod_log,"当前数据库查询花费时间%lu us",(end1_temp-st1_temp));
  326.     }
  327.     else
  328.     {
  329.         zlog_info(fzs_lib_mod_log,"The current database query cost time:%lu us",(end1_temp-st1_temp));
  330.     }
  331.     #endif

  332.     pthread_mutex_unlock(&mutex_cn);
  333.     return 0;
  334.         
  335. }

  336. 本代码实现中,没有实现主函数,实现了具体处理SQL语句及对获取的数据处理(没有解析出针对每一列),是作为通用函数处理的。
总结:
1,在对oracle数据库开发中,使用oracle公司开发的OCILIB库开发,相比oci更简单,具体OCILIB库的好处和实现demo请查阅OCILIB库说明;
2,在不使用OCILIB库函数解析从数据库获取的数据时,可以把SQL语句当着字符串处理,通过连接符使多列转为一列SQL语句,这样查询获取的数据也是一列;
3,对OCILIB库函数也要使用得当,掌握基本使用函数和使用技巧。

阅读(1027) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~