ESQL 资料(完全版)(5)

2019-04-08 19:07

CS_VOID *sd_sqldata; CS_SMALLINT sd_sqlind; CS_INT sd_sqllen; CS_VOID*sd_sqlmore; } sd_column[1]; } syb_sqlda;

typedef syb_sqlda SQLDA;

从上面这个定义看出,SQLDA是一种由两个不同部分组成的可变长数据结构。从位于SQLDA开端的sd_sqln到sd_sqld为固定部分,用于标志该SQLDA,并规定这一特定的SQLDA的长度。而后是一个或多个sd_column结构 ,用于标志列数据或参数。当用SQLDA把参数送到执行语句时,每一个参数都是一个sd_column结构;当用SQLDA返回输出列信息时,每一列都是一个sd_column 结构。具体每个元素的含义为:

lSd_Sqln。分配的sd_column结构的个数。等价于可以允许的最大输入参数的个数或输出列的个数。 lSd_Sqld。目前使用的sd_column结构的个数。

lSd_column[].sd_datafmt。标志同列相关的CS_DATAFMT结构。 lSd_column[].sd_Sqldata。指向数据的地址。注意,仅仅是一个地址。 lSd_column[].sd_sqllen。sd_sqldata指向的数据的长度。

lSd_column[].sd_Sqlind。代表是否为NULL。如果该列不允许为NULL,则该字段不赋值;如果该列允许为NULL,则:该字段若为0,表示数据值不为NULL,若为-1,表示数据值为NULL。 lSd_column[].sd_sqlmore。保留为将来使用。

下面我们来看一个具体的例子。这个例子是通过output_descriptor查询数据库中的数据,是通过input_descriptor传递参数。这个例子的作用是,模拟一个动态查询,并显示查询结果。动态查询的执行过程如下:

1)、如同构造动态UPDATE语句或DELETE语句的方法一样,程序在缓冲器中构造一个有效的SELECT语句。

2)、程序用PREPARE语句把动态查询语句送到DBMS,DBMS准备、确认和优化语句,并生成一个应用计划。

3)、动态DECLARE CURSOR语句说明查询游标,动态DECLARE CURSOR语句规定与动态SELECT语句有关的语句名称。如:例子中的statement。

4)、程序用DESCRIBE语句请求DBMS提供SQLDA中描述信息,即告诉程序有多少列查询结果、各列名称、数据类型和长度。DESCRIBE语句只用于动态查询。具体见下一节。

5)、为SQLDA申请存放一列查询结果的存储块(即:sqldata指向的数据区),也为SQLDA的列的指示符变量申请空间。程序把数据区地址和指示符变量地址送入SQLDA,以告诉DBMS向何处回送查询结果。

6)、动态格式的OPEN语句。即打开存放查询到的数据集(动态SELECT语句产生的数据)的第一行。 7)、动态格式的FETCH语句把游标当前行的结果送到SQLDA。(动态FETCH语句和静态FETCH语句的不同是:静态FETCH语句规定了用主变量接收数据;而动态FETCH语句是用SQLDA接收数据。)并把游标指向下一行结果集。 8)、CLOSE语句关闭游标。 具体程序如下: exec sql include sqlca; exec sql include sqlda;

...

/*input_ descriptor是通过SQLDA传递参数,output_descriptor是通过SQLDA返回列数据*/ SQLDA *input_descriptor, *output_descriptor; CS_SMALLINT small; CS_CHAR character[20]; /*申请空间*/

input_descriptor = (SQLDA *)malloc(SYB_SQLDA_SIZE(3)); /*设置参数的最大个数*/

input_descriptor->sqlda_sqln = 3; /*申请空间*/

output_descriptor = (SQLDA *)malloc(SYB_SQLDA_SIZE(3)); /*设置列数的最大值*/

output_descriptor->sqlda_sqln = 3; *p_retcode = CS_SUCCEED; /*连接数据库服务器*/

exec sql connect sa identified by password;

/* 创建一张example表,并插入一些例子数据,用于演示SQLDA的使用*/ exec sql drop table example;

exec sql create table example (fruit char(30), number int); exec sql insert example values (tangerine, 1); exec sql insert example values (pomegranate, 2); exec sql insert example values (banana, 3); /* 准备和描述查询语句*/ exec sql prepare statement from

select fruit from example where number = ?;

/*describe语句的作用是,将查询所需要的参数信息存放在input_descriptor中*/ exec sql describe input statement using descriptor input_descriptor;

/*设置SQLDA中指向参数数据的地址信息(sqldata)和数据长度(sqlda_sqllen)*/ input_descriptor->sqlda_column[0].sqlda_datafmt.datatype =CS_SMALLINT_TYPE; input_descriptor->sqlda_column[0].sqlda_sqldata = &small; input_descriptor->sqlda_column[0].sqlda_sqllen = sizeof(small); small = 2;

/*将查询语句的列信息存放在output_descriptor中*/

exec sql describe output statement using descriptor output_descriptor; if (output_descriptor->sqlda_sqld != 1 ||

output_descriptor->sqlda_column[0].sqlda_datafmt.datatype != CS_CHAR_TYPE) FAIL; else

printf(first describe output \\n); /*设置存放列数据的地址信息*/

output_descriptor->sqlda_column[0].sqlda_sqldata = character; output_descriptor->sqlda_column[0].sqlda_datafmt.maxlength = 20;

/*通过input_descriptor将输入参数带入查询语句,并将结果通过output_descriptor带出*/

exec sql execute statement into descriptor output_descriptor \\ using descriptor input_descriptor; /*打印结果---单行结果*/

printf(expected pomegranate, got %s\\n,character); /*释放申请的内存空间*/

exec sql deallocate prepare statement;

/* 多行结果示例。对多行查询语句做准备和描述操作*/ exec sql prepare statement from \\

select number from example where fruit = ?; /*为多行结果声明游标*/

exec sql declare c cursor for statement;

exec sql describe input statement using descriptor input_descriptor; /*设置查询的参数地址信息*/

input_descriptor->sqlda_column->sqlda_sqldata = character;

input_descriptor->sqlda_column->sqlda_datafmt.maxlength =CS_NULLTERM; /*设置参数值为banana,也可以提示用户输入这些信息*/ strcpy(character, banana);

input_descriptor->sqlda_column->sqlda_sqllen = CS_NULLTERM; /*打开游标*/

exec sql open c using descriptor input_descriptor; /*设置输出列的信息*/

exec sql describe output statement using descriptor output_descriptor; /*设置存放数据的地址信息*/

output_descriptor->sqlda_column->sqlda_sqldata = character;

output_descriptor->sqlda_column->sqlda_datafmt.datatype =CS_CHAR_TYPE; output_descriptor->sqlda_column->sqlda_datafmt.maxlength = 20; output_descriptor->sqlda_column->sqlda_sqllen = 20; output_descriptor->sqlda_column->sqlda_datafmt.format = (CS_FMT_NULLTERM | CS_FMT_PADBLANK); exec sql fetch c into descriptor output_descriptor; /*打印列的数据*/

printf(expected pomegranate, got %s\\n, character); exec sql commit work; ……….

上面这个例子是典型的动态查询程序。该程序中演示了PREPARE语句和DESCRIBE语句的处理方式,以及为程序中检索到的数据分配空间。要注意程序中如何设置sqlda_column结构中的的各个变量。这个程序也演示了OPEN、FETCH和CLOSE语句在动态查询中的应用。值得注意的是,FETCH语句只使用了SQLDA,不使用主变量。由于程序中预先申请了sqlda_column结构中的SQLDATA空间,所以DBMS知道将查询到的数据保存在何处。该程序还考虑了查询数据为NULL的处理。 值得注意的是,SQDA结构不是SQL标准。每个数据库厂商的实现方式有可能不同。 2.4.4 DESCRIBE语句

该语句只有动态SQL才有。该语句是在PREPARE语句之后,在OPEN语句之前使用。该语句的作用是,设置SQLDA中的描述信息,如:列名、数据类型和长度等。DESCRIBE语句的语法为:

DESCRIBE 语句名 INTO 描述符名

如:exec sql describe output statement using descriptor output_descriptor;。

在执行DESCRIBE前,用户必须给出SQLDA中的SQLN的值(表示最多有多少列),该值也说明了SQLDA中最多有多少个sqlda_column结构。然后,执行DESCRIBE语句,该语句填充每一个sqlda_column结构。每个sqlda_column结构中的相应列为: lSd_datafmt结构:列名等信息。 lSd_sqllen列:给出列的长度。

注意,sd_sqldata列不填充。由程序在FETCH语句之前,给出数据缓冲器地址和指示符地址。 2.5 两个例子程序 2.5.1 TELECOM程序 该程序是模拟电信费用查询。

#include #include #include #if defined ( DB2 )

#define SQLNOTFOUND 100 #include #elif defined ( ORA7 )

#define SQLNOTFOUND 1403 #endif

#if defined (SYBASE) #define SQLNOTFOUND100 #endif

EXEC SQL INCLUDE sqlca;

EXEC SQL BEGIN DECLARE SECTION; char user[30]; char passwd[30]; char Usr_name[61]; char Dev_no[9]; long Call_flg; char Called_arno[11]; char Called_no[15]; char Call_dat[21]; double Call_dur; double Call_rate; double Call_fee; double Add_fee; char as_dev_no[9];

EXEC SQL END DECLARE SECTION; void main(){

char statusbuf[1024], s[30]; /*连接到SQL SERVER服务器*/ printf(\\nplease enter your userid ); gets(user); printf(\\npassword ); gets(passwd);

exec sql connect :user identified by :passwd; exec sql use pubs2; /*输入想要查询的电话号码*/

printf(\\nPlease enter the telephone number:); gets(as_dev_no ); /*声明游标*/

EXEC SQL DECLARE c1 CURSOR FOR

SELECT bas_infot.Usr_name, auto10a_list.Dev_no, auto10a_list.Call_flg, auto10a_list.Called_arno, auto10a_list.Called_no

, auto10a_list.Call_dat, auto10a_list.Call_dur, auto10a_list.Call_rate, auto10a_list.Call_fee, FROM auto10a_list, bas_infot

WHERE ( auto10a_list.Dev_no = bas_infot.Dev_no ) AND auto10a_list.Dev_no = :as_dev_no; /*打开游标,指向查询相关电话信息的结果集*/ EXEC SQL OPEN c1; /* :rk.2:erk. */ do{

/*取出一行数据到各个变量*/ EXEC SQL FETCH c1 INTO

:Usr_name, :Dev_no, :Call_flg, :Called_arno, :Called_no, :Call_dat, :Call_dur, :Call_rate, :Call_fee, :Add_fee;

if( (sqlca.sqlcode == SQLNOTFOUND) || (sqlca.sqlcode <0) ) break; /*显示数据*/

printf(%s,%s,%d,%s,%s,%s,%7.0f,%8.3f,%7.2f,%6.2f\\n

, Usr_name, Dev_no, Call_flg, Called_arno, Called_no, Call_dat, Call_dur, Call_rate, Call_fee, Add_fee ); }while(1);

EXEC SQL CLOSE c1;

EXEC SQL DEALLOCATE CURSOR c1; Exec sql disconnect all; return (0); }

2.5.2 ADHOC程序

该程序的功能是:用户输入任意SQL语句,并执行和打印结果。

#include #include


ESQL 资料(完全版)(5).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:施工组织设计5

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: