荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: Peter (小飞侠), 信区: Program
标  题: 游标的使用
发信站: BBS 荔园晨风站 (Wed Jan 27 17:53:50 1999), 转信


    提到游标这个词,人们想到的是在屏幕上一个闪动的方框,用以指
示用户将要输入字符的位置。而在关系型数据库的SQL语言中,游标却
有另外的含义,它是存放结果集的数据对象。
    为什么要用到游标
    在某些PowerBuilder应用程序的开发中,您可能根本用不到游标
这样一个对象。因为在其它工具开发中很多需用游标实现的工作,在P
owerBuilder中却已有DataWindow来代劳了。事实上,DataWindow不仅
可以替代游标进行从后台数据库查询多条记录的复杂操作,而且还远
不止这些。但是同DataWindow和DataStore相比,游标也有其自身的优
点,比如系统资源占用少,操作灵活,可根据需要定义变量类型如全局
、实例或局部类型和访问类型如私有或公共等。

    游标的操作
    使用游标有四种基本的步骤:声明游标、打开游标、提取数据、
关闭游标。
    声明游标
    象使用其它类型的变量一样,使用一个游标之前,首先应当声明它
。游标的声明包括两个部分:游标的名称;这个游标所用到的SQL语句
。如要声明一个叫作Cus-tomerCursor的游标用以查询地址在北京的
客户的姓名、帐号及其余额,您可以编写如下代码:
    DECLARE CustomerCursor CURSOR FOR
    SELECT acct_no,name,balance
    FROM customer
    WHERE province="北京";
    在游标的声明中有一点值得注意的是,如同其它变量的声明一样,
声明游标的这一段代码行是不执行的,您不能将debug时的断点设在这
一代码行上,也不能用IF...END IF语句来声明两个同名的游标,如下
列的代码就是错误的。
    IF Is_prov="北京"THEN
    DECLARE CustomerCursor CURSOR FOR
    SELECT acct_no,name,balance
    FROM customer
    WHERE province="北京";
    ELSE
    DECLARE CustomerCursor CURSOR FOR
    SELECT acct_no,name,balance
    FROM customer
    WHERE province〈〉"北京";
    END IF

    打开游标
    声明了游标后在作其它操作之前,必须打开它。打开游标是执行
与其相关的一段SQL语句,例如打开上例声明的一个游标,我们只需键
入:
    OPEN CustomerCursor;
    由于打开游标是对数据库进行一些SQL SELECT的操作,它将耗费
一段时间,主要取决于您使用的系统性能和这条语句的复杂程度。如
果执行的时间较长,可以考虑将屏幕上显示的鼠标改为hourglass。

    提取数据
    当用OPEN语句打开了游标并在数据库中执行了查询后,您不能立
即利用在查询结果集中的数据。您必须用FETCH语句来取得数据。一
条FETCH语句一次可以将一条记录放入程序员指定的变量中。事实上,
FETCH语句是游标使用的核心。在DataWindow和DataStore中,执行了R
etrieve()函数以后,查询的所有结果全部可以得到;而使用游标,我
们只能逐条记录地得到查询结果。
    已经声明并打开一个游标后,我们就可以将数据放入任意的变量
中。在FETCH语句中您可以指定游标的名称和目标变量的名称。如下
例:
    FETCH CustmerCursor
    INTO:ls_acct_no,
    :ls_name,
    :ll_balance;
    从语法上讲,上面所述的就是一条合法的取数据的语句,但是一般
我们使用游标却还应当包括其它的部分。正如我们前面所谈到的,游
标只能一次从后台数据库中取一条记录,而在多数情况下,我们所想要
作的是在数据库中从第一条记录开始提取,一直到结束。所以我们一
般要将游标提取数据的语句放在一个循环体内,直至将结果集中的全
部数据提取后,跳出循环圈。通过检测SQLCA.SQL-CODE的值,可以得知
最后一条FETCH语句是否成功。一般,当SQLCODE值为0时表明一切正常
,100表示已经取到了结果集的末尾,而其它值均表明操作出了问题,这
样我们可以编写以下的代码:
    lb_continue=True
    ll_total=0
    DO WHILE lb_continue
    FETCH CustomerCursor
    INTO:ls_acct_no,
    :ls_name,
    :ll_balance;
    If sqlca.sqlcode=0 Then
    ll_total+=ll_balance
    Else
    lb_continue=False
    End If
    LOOP
    循环体的结构有多种,这里提到的是最常见的一种。也有的程序
员喜爱将一条FETCH语句放在循环体的前面,循环体内再放置另外一条
FETCH语句,并检测SQLCA.SQLCODE是否为100。但是这样做,维护时需
同时修改两条FETCH语句,稍麻烦了些。
    关闭游标
    在游标操作的最后请不要忘记关闭游标,这是一个好的编程习惯,
以使系统释放游标占用的资源。关闭游标的语句很简单:
    CLOSE CustomerCursor;

    使用Where子句子
    我们可以动态地定义游标中的Where子句的参数,例如在本例中我
们是直接定义了查询省份是北京的记录,但也许在应用中我们要使用
一个下拉式列表框,由用户来选择要查询的省份,我们该怎样做呢?
    我们在前面曾经提到过,DECLARE语句的作用只是定义一个游标,
在OPEN语句中这个游标才会真正地被执行。了解了这些,我们就可以
很方便地实现这样的功能,在DECLARE的Where子句中加入变量作参数,
如下所示:
    DECLARE CustomerCursor CURSOR FOR
    SELCECT acct_no,name,balance
    FROM customer
    WHERE province=:ls_province;
    ∥定义ls_province的值
    OPEN CustomerCursor;

    游标的类型
    同其它变量一样,我们也可以定义游标的访问类型:全局、共享、
实例或局部,游标变量的命名规范建议也同其它变量一样。
    游标的高级技巧
    尽管目前基于SQL语句的后台数据库所支持的语言都大致相当,但
对游标的支持却有着一些差异,例如对滚动游标支持。所谓滚动游标,
就是程序员可以指定游标向前后任意一个方向滚动。如在Informix中
,您甚至还可以将游标滚向结果集开头或末尾,使用的语句分别是FET
CH FIRST,FETCH LAST、FETCH PRIOR和FETCH NEXT。当程序员用FETC
H语句,其缺省是指FET CH NEXT。由于滚动是在数据库后台实现的,所
以滚动游标为用户编程提供了极大的方便。
    对游标支持的另一个不同是可修改游标。上述游标的使用都是指
只读游标,而象Oracle 、Sybase等数据库却另外支持可作修改的游标
。使用这样的数据库,您可以修改或删除当前游标所在的行。例如修
改当前游标所在行的用户的余额,我们可以如下操作:
    UPDATE customer
    SET balance=1000
    WHERE CURRENT of customerCursor;
    删除当前行的操作如下:
    DELETE FROM Customer
    WHERE CURRENT OF CustomerCursor;
    但是如果您当前使用的数据库是Sybase,您需要修改数据库的参
数,将游标可修改的值定为1,才能执行上述操作。这一赋值在连接数
据库的前后进行均可。
    SQLCA.DBParm="Cursor Update=1"
    另外一个内容是动态游标,也就是说您可以运行过程中动态地形
成游标的SELECT语句。这同在PowerBuilder中动态地使用嵌入式SQL
一样,需要用到DynamicStagingArea等数据类型,这已超出了本节的范
围。

--
※ 来源:.BBS 荔园晨风站 bbs.szu.edu.cn.[FROM: 192.168.1.3]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店