这时就可以对查询的SQL语句操作,使其要查询的每一项通过连接符连接在一起成为一项查询,
这时通过查询获取的数据就是一列的数据--一个字符串,再对字符串操作获取对应的每一项数据。
在编程实现中,可以把对SQL语句的操作看着是对字符串的操作,获取的结果也是看做字符串解析。
下面是简单实现,
环境:linux,oracle数据库,OCILIB库
点击(此处)折叠或打开
- 代码实现:
- /*存放每一行数据的结构体*/
- typedef struct _resultdata
- {
- int num;
- int row_len;
- SB1 *row_data;
- struct _resultdata *next;
- }ResultData;
- /***********************************************************
- *function:rs_link_insert
- *description:
- * 查询数据链表插入,将新的查询数据放进链表中
- *input: head:链表头
- * pi: 将要插进的新结点
- *
- *output: ResultData * :返回ResultData *指针,一般是链表
- *头结点
- * ********************************************************/
- ResultData *rs_link_insert(ResultData *head,ResultData *pi)
- {
- ResultData *pb = NULL;
- pb = head;
- //链表为空时,创建链表
- if(NULL == pb)
- {
- pb = pi;
- pi->next = NULL;
- head = pb;
-
- //rs_tail = pi;
- return head;
- }
- //不为空时,找到尾结点,并判断是否为空,为空将新结点
- //插入当前尾结点后
- //然后将新节点作为尾结点
- while(pb->next)
- {
- //pf = pb;
- pb = pb->next;
- }
- pb->next = pi;
- pi->next = NULL;
- return head;
-
- }
- /***********************************
- *function: sql_format_deal
- *description:
- * 将源字符串中’,‘替换为“||chr(1)||”
- *input: source:源字符串
- * search:格式化后的字符串
- *
- *output: 列值
- * ********************************/
- int sql_format_deal(char* csource_ext,char *cresult)
- {
- int iwork_bgn = 0;//单词标示
- int ibracket = 0;//括号标志
- int icol_cnt = 1;//列值
- char *csource = (char *)malloc(strlen(csource_ext) + 64);
- char *csrc = csource;
- char *cres = cresult;
- strcpy(csource, csource_ext);
- for(iwork_bgn=1,ibracket=0;*csrc;csrc++)
- {
- //如果到了from处,则不再替换
- if((!strncasecmp(csrc,"from",4))&&iwork_bgn)
- {
- if(csrc[4]==0 || strchr(" \t\r\n",csrc[4]))
- {
- break;
- }
- }
- //将csrc中‘,’替换为“||chr(1)||”,注:括号内不处理
- if(!ibracket && *csrc == ',')
- {
- // 一个逗号则替换为||chr(1)||,两个逗号作为一个逗号(说明要单作为1列处理)
- if(csrc[1]==',')
- {
- // 保存当前逗号,跳过pi[1]的逗号
- *cres++ = *csrc++;
- icol_cnt++;
- }
- else
- {
- //strcpy(cres,"||chr(1)||");
- strcpy(cres,"||chr(1)||");
- cres += strlen(cres);//是"||chr(1)||"的长度
- }
- }
- else
- {
- *cres++ = *csrc;
- // 判断是否一个词的开始
- iwork_bgn = strchr(" \t\r\n",*csrc)?1:0;
- // 判断是否在括号内
- if('(' == *csrc)
- {
- ibracket++;
- }
- if(')' == *csrc)
- {
- ibracket--;
- }
- }
- }
- // from后面的内容全部拷贝
- for(;*csrc;csrc++)
- {
- *cres++ = *csrc;
- }
- *cres = '\0';
- FZS_FREE(csource);
- return icol_cnt;
- }
- /***********************************
- *function: db_select_data
- *description:
- * 查询SQL语句,获得查询数据,将数据存放在rs_data内
- *
- *
- *input: CN:数据路连接对象
- * SQL:SQL执行语句
- * *row_num:查询数据行数
- * rs_data:存放查询后的数据`
- *
- *output: >=0:sucess <0:fail
- *注意:开辟了rs_data及rs_link链表内存空间
- * 同时释放了sele_data及se_link链表内存空间
- * rs_data及rs_link内存空间由函数
- * db_get_le_data释放
- *
- * 开辟了format_sql空间,并在用完后释放
- * ********************************/
- int db_select_data(OCI_Connection *cn, char* sql,int *row_num,ResultData **rs_data)
- {
- OCI_Statement *st = NULL;
- OCI_Resultset *rs = NULL;
- int icolmn_cnt = 0;
- int icnt = 0;
- ResultData *pb_data = NULL;
- ResultData *rs_head = NULL;
- ResultData *rs_node = NULL;
- int isql_len = 0;
- SB1 *format_sql = NULL;
- SB1 *ptemp = NULL;
- SB1 *p1temp = NULL;
- SB1 buf_data[MAX_ROW_LENGTH];
- SB1 *pbuf_data = NULL;
- int itemp1 = 0;
- //char *ptmp = 0;
-
- //对SQL语句断言
- assert(sql);
- //判断数据库连接对象是否为空
- if(NULL == cn)
- {
- zlog_error(fzs_lib_mod_log,"---no connect to oracle,please check connect");
- return -1;
- }
- pthread_mutex_lock(&mutex_cn);
- //zlog_error(fzs_lib_mod_log,"cn addr:%p",cn);
- //通过数据库连接对象获得SQL语句执行对象
- st = OCI_StatementCreate(cn);
- if(NULL == st)
- {
- //printf("file:%s---line:%d---OCI_StatementCreate---fail\r\n",POS_INFO);
- zlog_error(fzs_lib_mod_log,"---OCI_StatementCreate---fail");
- OCI_err_handler(OCI_GetLastError());
- pthread_mutex_unlock(&mutex_cn);
- return -1;
- }
- //sql格式化后的结构
- isql_len = strlen(sql)+1024;
- //分配内存空间
- format_sql = (SB1*)FZS_MALLOC(isql_len);
- memset(format_sql,0,isql_len);
- //格式化SQL语句
- icolmn_cnt = sql_format_deal(sql,format_sql);//多列的话目前没有处理
- //printf("file:%s---line:%d-format_sql=%s\r\n",POS_INFO,format_sql);
- zlog_debug(fzs_lib_mod_log,"-format_sql=%s",format_sql);
- //printf("file:%s---line:%d-icolmn_cnt=%d\r\n",POS_INFO,icolmn_cnt);
- zlog_debug(fzs_lib_mod_log,"-icolmn_cnt=%d",icolmn_cnt);
- //执行SQL语句
- if(!OCI_ExecuteStmt(st,format_sql))// format_sql 是格式化后的语句
- {
- zlog_error(fzs_lib_mod_log,"-OCI_ExecuteStmt---fail");
- OCI_err_handler(OCI_GetLastError());
- pthread_mutex_unlock(&mutex_cn);
- return -1;
- }
-
- //获取结果集对象
- zlog_debug(fzs_lib_mod_log,"-OCI_ExecuteStmt---OK!!!");
- rs = OCI_GetResultset(st);
- if(NULL == rs)
- {
- zlog_error(fzs_lib_mod_log,"OCI_ExecuteStmt---fail");
- OCI_err_handler(OCI_GetLastError());
- pthread_mutex_unlock(&mutex_cn);
- return -1;
- }
- //对rs结果集中的数据处理,将rs数据存到rs_link中,并获得每行数据长度
- while(OCI_FetchNext(rs))
- {
- icnt++;
- //每次获得数据前,清空buf内数据
- //printf("%s\n",OCI_GetString(rs,1));
- memset(buf_data,0,MAX_ROW_LENGTH);
- pbuf_data = buf_data;
- for(itemp1 = 0; itemp1 < icolmn_cnt; itemp1++)
- {
- pbuf_data += strlen(pbuf_data);
- if(itemp1 > 0)
- *pbuf_data++ = 0x01;
- sprintf(pbuf_data, OCI_GetString(rs, itemp1 + 1));
- }
- //printf("file:%s--line:%d--buf_data=%s\r\n",POS_INFO,buf_data);
- zlog_debug(fzs_lib_mod_log,"--buf_data=%s",buf_data);
- //irow_len = strlen(buf_data)+1;
- //printf("file:%s--line:%d--*len=%d\r\n",POS_INFO,*len);
- //zlog_debug(fzs_lib_mod_log,"*len=%d",*len);
- //给pb_data分配内存空间
- pb_data = (ResultData*)malloc(sizeof(ResultData));
-
- //分配内存失败
- if(pb_data == NULL)
- {
-
- //printf("SelectData--pb_data malloc memory fail\r\n");
- zlog_error(fzs_lib_mod_log,"OCI_ExecuteStmt---fail");
- //释放返回集
- if(rs)
- {
- OCI_ReleaseResultsets(st);
- //printf("file:%s--line:%d--OCI_ReleaseResultsets(st) success\r\n",POS_INFO);
- }
- //清除声明
- if(st)
- {
- OCI_StatementFree(st);
- //printf("file:%s--line:%d--OCI_StatementFree(st) success\r\n",POS_INFO);
- }
- pthread_mutex_unlock(&mutex_cn);
- return -1;
- }
- pb_data->row_data = (SB1*)malloc((strlen(buf_data)+1));
-
- //分配内存失败
- if(pb_data->row_data == NULL)
- {
- //printf("SelectData--pb_data->row_data malloc memory fail\r\n");
- zlog_error(fzs_lib_mod_log,"SelectData--pb_data->row_data malloc memory fail");
- free(pb_data);
- //释放返回集
- if(rs)
- {
- OCI_ReleaseResultsets(st);
- //printf("file:%s--line:%d--OCI_ReleaseResultsets(st) success\r\n",POS_INFO);
- }
- //清除声明
- if(st)
- {
- OCI_StatementFree(st);
- //printf("file:%s--line:%d--OCI_StatementFree(st) success\r\n",POS_INFO);
- }
- pthread_mutex_unlock(&mutex_cn);
- return -1;
- }
- pb_data->num = icnt;
- pb_data->row_len = strlen(buf_data)+1;
- //数据全部Copy过来,不是地址赋值过来
- memcpy(pb_data->row_data,buf_data,strlen(buf_data)+1);//sizeof(rs)==4,forever
- pb_data->row_data[strlen(buf_data)] = '\0';
- //将每一行数据作为一个结点存放在链表中
- //printf("file:%s--line:%d--pb_data->row_data=%s\r\n",POS_INFO,pb_data->row_data);
- zlog_debug(fzs_lib_mod_log,"--pb_data->row_data=%s",pb_data->row_data);
- rs_head = rs_link_insert(rs_head,pb_data);
- }
- //总行数
- *row_num = icnt;
- *rs_data = rs_head;
- //将rs_head指向空指针
- rs_head = NULL;
-
- //rs_link_print(*rs_data);
-
- //将每行数据内的0x1替换为0x0
- for(rs_node=*rs_data;rs_node;rs_node=rs_node->next)
- {
- for(ptemp = rs_node->row_data,p1temp = ptemp+rs_node->row_len;ptemp < p1temp;ptemp++)
- {
-
- if(1 == *ptemp)
- {
- // printf("file:%s--line:%d--p=%c\r\n",POS_INFO,*p);
- // zlog_debug(fzs_lib_mod_log,"--p=%c",*p);
- *ptemp = 0;
- // printf("file:%s--line:%d--p=%c\r\n",POS_INFO,*p);
- // zlog_debug(fzs_lib_mod_log,"--p=%c",*p);
- }
- }
- //printf("file:%s--line:%d--rs_node->row_data=%s\r\n",POS_INFO,rs_node->row_data);
- zlog_debug(fzs_lib_mod_log,"--rs_node->row_data=%s",rs_node->row_data);
- }
- //rs_link_print(*rs_data);
- //释放format_sql内存空间
- free(format_sql);
- //释放返回集
- if(rs)
- {
- OCI_ReleaseResultsets(st);
- //printf("file:%s--line:%d--OCI_ReleaseResultsets(st) success\r\n",POS_INFO);
- }
- //清除声明
- if(st)
- {
- OCI_StatementFree(st);
- //printf("file:%s--line:%d--OCI_StatementFree(st) success\r\n",POS_INFO);
- }
- #ifdef SWITCH_LOG
- if(1 == db_en_chs_flag)
- {
- zlog_info(fzs_lib_mod_log,"当前数据库查询花费时间%lu us",(end1_temp-st1_temp));
- }
- else
- {
- zlog_info(fzs_lib_mod_log,"The current database query cost time:%lu us",(end1_temp-st1_temp));
- }
- #endif
- pthread_mutex_unlock(&mutex_cn);
- return 0;
-
- }
- 本代码实现中,没有实现主函数,实现了具体处理SQL语句及对获取的数据处理(没有解析出针对每一列),是作为通用函数处理的。
1,在对oracle数据库开发中,使用oracle公司开发的OCILIB库开发,相比oci更简单,具体OCILIB库的好处和实现demo请查阅OCILIB库说明;
2,在不使用OCILIB库函数解析从数据库获取的数据时,可以把SQL语句当着字符串处理,通过连接符使多列转为一列SQL语句,这样查询获取的数据也是一列;
3,对OCILIB库函数也要使用得当,掌握基本使用函数和使用技巧。