Database 版 (精华区)

发信人: wodeji (西西), 信区: Database
标  题: [转载] PowerBuilder 开 发 系 列 谈 (11) 
发信站: 紫 丁 香 (Tue Sep 29 17:51:20 1998), 站内信件

【 以下文字转载自 Programming 讨论区 】
【 原文由 two 所发表 】


 ---- 提 到 游 标 这 个 词, 人 们 想 到 的 是 在 屏 幕 上 一 个 闪 动 的 方 框, 用 以 指 示
 用 户 将 要 输 入 字 符 的 位 置。 而 在 关 系 型 数 据 库 的SQL 语 言 中, 游 标 却 有
 另 外 的 含 义, 它 是 存 放 结 果 集 的 数 据 对 象。 

                            为 什 么 要 用 到 游 标 

 ---- 在 某 些PowerBuilder 应 用 程 序 的 开 发 中, 您 可 能 根 本 用 不 到 游 标 这 样 一
 个 对 象。 因 为 在 其 它 工 具 开 发 中 很 多 需 用 游 标 实 现 的 工 作, 在PowerBuilder
 中 却 已 有DataWin-dow 来 代 劳 了。 事 实 上,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 CustmerCur-sor 

 ----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 CustomerCur-sor 

 ----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。 当 程 序 员 用FETCH 语 句, 其
 缺 省 是 指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 一 样, 需
 要 用 到DynamicStagin-gArea 等 数 据 类 型, 这 已 超 出 了 本 节 的 范 围。 

                       



--
※ 来源:.紫 丁 香 bbs.hit.edu.cn.[FROM: 202.97.236.132]
--
※ 转载:.紫 丁 香 bbs.hit.edu.cn.[FROM: whs.hit.edu.cn]
--
※ 转载:.紫 丁 香 bbs.hit.edu.cn.[FROM: cadcam.hit.edu.c]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:3.532毫秒