嵌入式SQL语言imp(5)

2019-04-22 08:33

char szFirstName[30];

EXEC SQL END DECLARE SECTION;

EXEC SQL

DECLARE author_cursor CURSOR FOR

SELECT au_fname FROM authors WHERE au_lname = :szLastName;

EXEC SQL OPEN author_cursor;

EXEC SQL FETCH author_cursor INTO :szFirstName;

动态游标和静态游标不同。以下是动态游标使用的句法(请参照本小节后面的例子来理解动态游标)。 1)、声明游标:

对于动态游标,在DECLARE CURSOR语句中不包含SELECT语句。而是,定义了在PREPARE中的语句名,PREPARE语句规定与查询相关的语句名称。具体语法为:

exec sql [at connection_name] declare cursor_name

cursor for statement_name;

如:EXEC SQL DECLARE author_cursor CURSOR FOR select_statement;

值得注意的是,声明动态游标是一个可执行语句,应该在PREPARE语句后执行。 2)、打开游标

完整语法为:OPEN 游标名 [USING 主变量名 | DESCRIPTOR 描述名]

在动态游标中,OPEN语句的作用是使DBMS定位相关的游标在第一行查询结果前。当OPEN语句成功执行完毕后,游标处于打开状态,并为FETCH语句做准备。OPEN语句执行一条由PREPARE语句预编译的语句。如果动态查询正文中包含有一个或多个参数标志时,OPEN语句必须为这些参数提供参数值。USING子句的作用就是规定参数值。可以使用主变量提供参数值,也可以通过描述名(即SQLDA)提供参数值。如:EXEC SQL OPEN author_cursor USING :szLastName;。 3)、取一行值

FETCH语法为:FETCH 游标名 INTO USING DESCRIPTOR 描述符名。 动态FETCH语句的作用是,把游标移到下一行,并把这一行的各列值送到SQLDA中。注意的是,静态FETCH语句的作用是用主变量表接收查询到的列值。在方法3中,使用的是静态FETCH语句获得值。动态FETCH语句只在方法4中使用。 4)、关闭游标

如:EXEC SQL CLOSE c1;

关闭游标的同时,会释放由游标添加的锁和放弃未处理的数据。在关闭游标前,该游标必须已经声明和打开。另外,程序终止时,系统会自动关闭所有打开的游标。

总之,在动态游标的DECLARE CURSOR语句中不包含SELECT语句。而是,定义了在PREPARE中的语句名,用PREPARE语句规定与查询相关的语句名称。当PREPARE语句中的语句包含了参数,那么在OPEN语句中必须指定提供参数值的主变量或SQLDA。动态DECLARE CURSOR语句是一个可执行语句。该子句必须在OPEN、FETCH、CLOSE语句之前使用。请看下面这个例子,描述了完成方法3的五个步骤:PREPARE、DECLARE、OPEN、FETCH和CLOSE。 ……

EXEC SQL BEGIN DECLARE SECTION;

21

char szCommand[] = \char szLastName[] = \char szFirstName[30];

EXEC SQL END DECLARE SECTION;

EXEC SQL PREPARE select_statement FROM :szCommand;

EXEC SQL DECLARE author_cursor CURSOR FOR select_statement; EXEC SQL OPEN author_cursor USING :szLastName; EXEC SQL FETCH author_cursor INTO :szFirstName; EXEC SQL CLOSE author_cursor; ………

下面是一个实现方法3的实际例子。提示用户输入排序的条件,并把符合条件的书信息显示出来。 ……

exec sql begin declare section; CS_CHAR sqlstring[200]; CS_FLOAT bookprice,condprice; CS_CHAR booktitle[200]; exec sql end declare section; char orderby[150];

exec sql whenever sqlerror call err_p(); exec sql whenever sqlwarning call warn_p(); strcpy(sqlstring,

\where price>? order by \

printf(\scanf(\strcat(sqlstring, orderby);

exec sql prepare select_state from :sqlstring; exec sql declare select_cur cursor for select_state;

condprice = 10; /* 可以提示用户输入这个值*/ exec sql open select_cur using :condprice; exec sql whenever not found goto end; for (;;) {

exec sql fetch select_cur into :booktitle,:bookprice; printf(\booktitle, bookprice); } end:

exec sql close select_cur; exec sql commit work; ………..

22

2.4.3 SQLDA

要实现方法4,则需要使用SQLDA(也可以使用SQL Descriptors,请读者参阅帮助信息)。可以通过SQLDA为嵌入SQL语句提供不确定的输入数据和从嵌入SQ语句中输出不确定数据。理解SQLDA的结构是理解动态SQL的关键。

我们知道,动态SQL语句在编译时可能不知道有多少列信息。在嵌入SQL语句中,这些不确定的数据是通过SQLDA完成的。SQLDA的结构非常灵活,在该结构的固定部分,指明了多少列等信息(如下图中的sqld=2,表示为两列信息),在该结构的后面,有一个可变长的结构(sd_column结构),说明每列的信息。

SQLDA结构 Sd_Sqld=2 数据 Sd_column ……

Sd_column结构 Sd_datafmt Sd_Sqllen 列1 数据 Sd_sqldata ….. : : Sd_datafmt 列2 : Sd_Sqllen Sd_Sqldata : ….. :

图6-2 SQLDA结构示例 具体SQLDA的结构在sqlda.h中定义,是:

typedef struct _sqlda { CS_SMALLINT sd_sqln; CS_SMALLINT sd_sqld; struct _sd_column { CS_DATAFMT sd_datafmt; 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;

23

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

? Sd_Sqln。分配的sd_column结构的个数。等价于可以允许的最大输入参数的个数或输

出列的个数。

? Sd_Sqld。目前使用的sd_column结构的个数。

? Sd_column[].sd_datafmt。标志同列相关的CS_DATAFMT结构。

? Sd_column[].sd_Sqldata。指向数据的地址。注意,仅仅是一个地址。 ? Sd_column[].sd_sqllen。sd_sqldata指向的数据的长度。

? Sd_column[].sd_Sqlind。代表是否为NULL。如果该列不允许为NULL,则该字段不赋

值;如果该列允许为NULL,则:该字段若为0,表示数据值不为NULL,若为-1,表示数据值为NULL。

? Sd_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;

24

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 \

/* 创建一张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

\

/*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(\/*设置存放列数据的地址信息*/

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; /*打印结果---单行结果*/

25


嵌入式SQL语言imp(5).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:苏教版六年级语文上册一课一练(整理)

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

马上注册会员

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