项目开发中,需要从数据库查询数据,在不使用数据库库函数的情况下对获取的数据解析,
这时就可以对查询的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库函数也要使用得当,掌握基本使用函数和使用技巧。
阅读(1094) | 评论(0) | 转发(0) |