esql/c (3)

zjpwm 2003-08-20 01:07:26
第三章 查 询

在ESQL程序中,查询可以分为两大类型:返回一行的查询和返回多行的查询.对于查询,我们不仅对其执行得成功与否感兴趣,其结果更为有用.多行查询要用到游标的概念,本章就介绍查询语句和游标的概念和使用.

3.1 SELECT 语句
SELECT语句是用于完成查询功能的SQL语句,查询语句因为有返回的结果,故ESQL中的SELECT语句比SQL的SELECT语句多一INTO子句,INTO子句的主变量表对应于程序中主变量,用于存放查询返回的结果.
SELECT语句格式如下:
EXEC SQL SELECT <列名> [,<列名>[,...]] INTO <主变量表>
FROM <表名> [,<表名>[,...]] [WHERE <检索条件>];
其中:1.检索条件中允许有主变量和嵌套子查询语句.
2.INTO后的主变量可以是数组.
3.主变量前要用":"标志.
执行该语句时,COBASE找出表中满足检索条件的行,并把结果传送到INTO子句中所对应的主变量中.该语句的查询结果可以是一行或多行.WHERE后的主变量叫输入主变量,它提供了查询所需的信息.INTO子句中的主变量叫输出主变量,它保存SELECT语句运行后的结果.

例题程序3 (返回一行的查询)
/*=============================================================================
This is a sample program which uses SELECT statement of Esql.
It is an example of how to do queries that return one row.
==============================================================================*/

EXEC SQL BEGIN DECLARE SECTION ;
INT status;
CHAR sno[10],sname[10],city[10],isno[10];
EXEC SQL END DECLARE SECTION ;
EXEC SQL INCLUDE USERCA;
main()
{
EXEC SQL CONNECT "cobase:cobase" ; /* log into COBASE */</P><P>printf("input the sno for update:");
scanf("%s",sno);
EXEC SQL SELECT sno,sname,status,city
INTO :sno , :sname ,:status,:city
from S_TEST WHERE sno=:sno;
printf("sno: %s ;",sno);
printf("sname: %s ;",sname);
printf("status: %d ;",status);
printf("city: %s ;",city);
EXEC SQL COMMIT;
EXEC SQL DISCONNECT;
exit(0);

}
例题程序4 (返回多行的查询)

/*=============================================================================
This is a sample program which uses SELECT statement of Esql.
It is an example of how to do queries that return more than
one row.
==============================================================================*/

EXEC SQL BEGIN DECLARE SECTION ;
INT status[10];
CHAR sno[10][10],sname[10][15],city[10][20],isno[10];
EXEC SQL END DECLARE SECTION ;
EXEC SQL INCLUDE USERCA;
main()
{ int i;
EXEC SQL CONNECT "cobase:cobase" ; /* log into COBASE */
for(i=0;i<10;i++)
{
strcpy(sno[i],"ttttt");
strcpy(sname[i],"ttttt");
strcpy(city[i],"ttttt");
status[i]=1000;
}
EXEC SQL SELECT sno,sname,status,city
INTO :sno , :sname ,:status,:city
from S_TEST;
printf("sno sname status city");
for(i=0;i<10;i++)
{ printf("%8s %8s %8d %8s ",sno[i],sname[i],status[i],city[i]);
getchar();
}
EXEC SQL COMMIT;
EXEC SQL DISCONNECT;
}

3.2 游标的使用
我们知道SQL语言是一种面向集合的语言,而普通的高级语言则是面向记录的语言,要想使SQL语言能与宿主语言通讯,ESQL提供了游标操作,能把SQL的集合操作结果,按单个记录方式取出,赋于主变量进行进一步的处理.
如果查询结果返回多行或不知返回多少行,就可使用带游标的SELECT语句.一个游标(CURSOR)是一个COBASE和ESQL使用的工作区域,COBASE使用这个工作区存放着一个查询结果 .一个已命名的游标是和一条SELECT语句相关联.一个游标必须首先定义(同一个查询相关联),然后用三条可运行的SQL语句使用游标,以操纵数据.四条操纵游标的命令如下:
.DECLRE CURSOR
.OPEN CURSOR
.FETCH
.CLOSE CURSOR
DECLARE CURSOR 语句用来定义一游标,此时游标处于关闭状态.用OPEN CURSOR语句打开游标后,就可用它从相关的查询中取出多于一行的结果.所有满足查询条件的行组成一个集合,叫做游标活动集.通过FETCH取操作,活动集中的每一行可以一个一个的返回,当查询作完后,游标就可以用CLOSE CURSOR 语句关闭.

3.2.1DECLARE CURSOR 定义游标语句:
ESQL中的DECLARE CURSOR语句定义游标,赋给它一个与查询相关的游标名.该语句的格式为:
EXEC SQL DECLARE <游标名> CURSOR FOR
<SELECT 语句> [FOR UPDATE];
其中:(1)SELECT语句应不含INTO子句.
(2)若无FOR UPDATE 则无法 执行UPDATE(定位)和DELETE(定位)语句.

定义游标的DECLARE语句必须出现在程序中对游标进行操作的所有语句之前, ESQL不能引 用没有说明的游标,游标的定义范围是整个程序.程序中可包含多个DECLARE语 句,这些语句定义了不同的游标,并把游标与不同的查询联系在一起,所以在同一个程序中的两个DECLARE语句中不能说明同一个游标名.

3.2.2 OPEN CURSOR 打开游标语句
ESQL中OPEN CURSOR语句格式如下:

EXEC SQL OPEN <游标名>;

OPEN语句决定了满足查询的行的集合,游标处于打开状态,它的活动集就是满足WHERE子句条件的行的集合.这时,游标处在活动集的第一行的 前面.

3.2.3 FETCH CURSOR 语句
ESQL中的FETCH CURSOR语句读出活动集中的行,并把结果送到输出主变量,输出主变量是在相关的FETCH语句中定义的.其 格式如下:

EXEC SQL FETCH <游标名> INTO <主变量表>;

游标必须先定义,然后再打开,只有当游标处于打开状态时,才执行FETCH语句.在第一次运行FETCH时,游标从活动集的第一行前移到当前第一行,使这一行成为当前行.每次运行FETCH时游标在活动集中向前移,把选出的结果送到主变量表中指定的输出主变量中.
如果游标活动集中是空的,或所有的行已经被取走,COBASE就返回一代码.(USERCA.SQLCODE==2000).
游标只可在活动集中向前移动,COBASE无法取到已经用FETCH取过的行,要想再取这一行,就必须关闭游标,再重新打开它. </P><P>3.2.4 CLOSE CURSOR 关闭游标语句
当取完活动集中所有行后,必须关闭游标,以释放与该游标的关的资源.其格式如下:
EXEC SQL CLOSE <游 标名>;

例题程序5 (使用游标的查询)
/*=============================================================================
This is a sample program which uses Cursor.Include DECLARE,
OPEN,FETCH and CLOSE cursor name.
It is an example of how to do queries that return more than
one row.
==============================================================================*/

EXEC SQL BEGIN DECLARE SECTION ;
INT status;
CHAR sno[10],sname[15],city[20];
EXEC SQL END DECLARE SECTION ;
EXEC SQL INCLUDE USERCA;
main()
{
int i;
printf("Now exec connect ...");
EXEC SQL CONNECT "cobase:cobase" ; /* log into COBASE */
printf("Now exec declare_open_fetch_close cursor ...");
/* Declare statement name ---"s1" for INSERT statement */
EXEC SQL DECLARE cursor1 CURSOR FOR SELECT * FROM S_TEST;
EXEC SQL OPEN cursor1 ;
printf("sno sname status city\n ");
do
{
EXEC SQL FETCH cursor1 INTO :sno,:sname,:status,:city ;
If (userca.sqlcode==2000) break;
printf("%8s %8s %8d %8s \n",sno,sname,status,city);
getchar();

}while(1);
EXEC SQL CLOSE cursor1 ;
EXEC SQL COMMIT;
EXEC SQL DISCONNECT;
}
3.3 定位修改和删除语句
COBASE支持SQL格式" CURRENT OF CURSOR".这条语句将指向一个游标中最新取出的行,以用于修改和删除操作.该语句必须在取操作之后使用 ,它等同于存储一个ROWID,并使用它.其格式如下:
(1) EXEC SQL
UPDATE <表名>
SET <列名> = <值表达式> | NULL
[,<列名> = <值表达式> | NULL ....]
WHERE CURRENT OF <游标名> ;
(2) EXEC SQL
UPDATE <表名>
SET ( <列名表> ) = ( <子查询> )
WHERE CURRENT OF <游标名> ;
(3) EXEC SQL DELETE FROM <表名>
WHERE CURRENT OF <游标名> ;
这些语句执行在游标名的当前行下更新或修改.其中在值表达式或子查询中出现的主变量前应有":"标志.
...全文
118 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

1,194

社区成员

发帖
与我相关
我的任务
社区描述
其他数据库开发 Informix
社区管理员
  • Informix社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧