设为首页 加入收藏

TOP

C语言访问INFORMIX数据库 ― SQLDA使用(一)
2014-11-23 23:24:24 来源: 作者: 【 】 浏览:1
Tags:语言 访问 INFORMIX 数据库 SQLDA 使用

一、前言概述
之前写过3篇关于C语言访问INFORMIX数据的博文:第一篇讲述ESQL基本语法;第二篇讲述接口实现;第三篇讲述SQLDA结构。此篇根据以上3篇的内容,进一步分析执行动态查找语句中关于ifx_sqlda_t的使用。

二、用法分析

2.1 DESCRIBE ... INTO

在接口实现中的db_ifx_mquery()函数中有这样一段代码:

代码段一:

[html]
ifx_sqlda_t *sqlda = NULL;

...

EXEC SQL DESCRIBE QUERY_SQLSTMT_ID INTO sqlda;
代码分析:

定义变量sqlda为一个空指针,但执行DESCRIBE ... INTO后,就能对sqlda进行其他操作处理了。我想这时每个人看到这里心中都有一个疑问:DESCRIBE ... INTO到底对空指针sqlda做了什么处理?

①、分配空间

1. 定义变量sqlda为空指针,但DESCRIBE...INTO之后就能够进行操作,很显然,DESCRIBE...INTO为变量sqlda分配了内存空间

2. 分配的空间包括:sqlda和sqlda->sqlvar。且sqlda->sqlvar指向大小为sqld*sizeof(struct sqlvar_struct)内存块。(sqlvar:指向struct sqlvar_struct结构体,即指向描述第一列信息的sqlvar结构体)

3. 但未给sqlda->sqlvar中其他指针分配内存

②、获取语句信息,并存放在ifx_sqlda_t结构中

获取的语句信息包括:

sqld:使用的sqlvar结构的个数,即:输出列的个数

sqlvar:指向struct sqlvar_struct结构体,即:指向描述第一列信息的sqlvar结构体

desc_name:sqlda名称

desc_occ:sqlda结构的大小

sqltype:代表参数或列的数据类型。它是一个整数数据类型代码。

sqllen:代表传送数据的长度

sqlname:代表列名或变量名

有了以上的语句信息,就可以为后续数据行的空间分配提供依据。

举例分析:

假设需执行查询2列的SQL语句,在执行DESCRIBE...INTO后,变量sqlda的内存结构图为:

图1 变量sqlda的内存结构图

2.2 SQLDA初始化

代码段二:

[cpp]
/* 依据sqlda的信息,初始化其他数据 */
int db_ifx_init_sqlda(db_ifx_cntx_t *context, ifx_sqlda_t *sqlda)
{
int ret = 0,
idx = 0,
msg_len = 0,
row_size = 0,
alloc_num = 0;
struct sqlvar_struct *sqlvar = NULL;

context->result = sqlda;

/* Step 1. 获取一行数据的长度 */
sqlvar = sqlda->sqlvar;
for(idx=0; idxsqld; idx++, sqlvar++)
{
/* 非C下一行数据的长度 */
msg_len += sqlvar->sqllen;

/* 为col->sqllen 重新赋值,该值是在C下的大小。
如:在数据库中的字符串,在C中应该多一个字节空间来存放NULL的结束符 */
sqlvar->sqllen = rtypmsize(sqlvar->sqltype, sqlvar->sqllen);

/* C下一行数据的长度 */
row_size += sqlvar->sqllen;
}

/* Step2. 设置FetArrSize的值 */
if(-1 == FetArrSize)
{
if(FetBufSize < msg_len)
{
FetBufSize = msg_len;
}
FetArrSize = FetBufSize/msglen;
}

alloc_num = (FetArrSize <= 0) 1:FetArrSize;

/* Step3. 初始化列:列的取值分配空间等 */
sqlvar = sqlda->sqlvar;
for(idx=0; idxsqld; idx++, sqlvar++)
{
ret = db_ifx_set_sqltype(sqlvar);
if(ret < 0)
{
return ret;
}

ret = db_ifx_init_sqldata(context, sqlvar, alloc_num);
if(ret < 0)
{
return ret;
}
}

return msg_len;
}
代码说明:
1. 全局变量FetBufSize、FetArrSize说明
FetBufSize:是INFORMIX中的全局变量。此值决定了取数据库数据时的缓存大小
FetArrSize:是INFORMIX中的全局变量。此值决定了一次FETCH可以从数据库取多少行数据

2. 变量alloc_num的值决定了一次FETCH可以从数据库取多少行数据,其将成为后续初始化过程中空间申请大小的依据

代码段三:

[cpp]
/* 依据数据库中的数据类型,设置C下数据类型 */
int db_ifx_set_sqltype(struct sqlvar_struct *sqlvar)
{
switch(sqlvar->sqltype)
{
case SQLBOOL:
{
sqlvar->sqltype = CBOOLTYPE;
break;
}
case SQLSMINT:
{
sqlvar->sqltype = CSHORTTYPE;
break;
}
case SQLINT:
{
sqlvar->sqltype = CINTTYPE;
break;
}
case SQLINT8:
case SQLSERIAL:
case SQLSERI

首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇防止对特定的函数下CC断点 下一篇C语言连接 Access 数据库

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: