Database 版 (精华区)

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

【 以下文字转载自 Programming 讨论区 】
【 原文由 two 所发表 】
PowerBuilder系 列 讲 座 ( 2 9 ) 

        我 们 在 使 用PowerBuilder 编 程 的 过 程 中, 总 是 不 可 避 免 地 要 用 到BLOB(Binary
 Large Objects , 大 型 二 进 制 对 象) 字 段 及 其 相 关 函 数。 这 里 我 们 来 介 绍 一 下 使
 用BLOB 的 方 法 

 何 时 使 用BLOB 数 据 类 型 

        在 下 列 情 况 下, 我 们 可 能 要 在PowerScript 语 言 中 使 用 到BLOB 数 据 类 型: 

      您 要 将OLE 对 象( 如 图 形、 声 音 等) 存 入 您 的 数 据 库 中; 
      您 要 将 大 型 的 二 进 制 对 象 存 入 您 的 数 据 库 中; 
      您 所 要 操 纵 的 文 本 对 象 过 大, 以 致 于 一 般 的 字 符 串 函 数 无 法 对 其 操 作; 
      您 所 使 用 数 据 库 的 数 据 类 型PowerBuilder 不 能 支 持, 如SQLBase 中longvarchar 这
      一 数 据 类 型, 所 以 您 只 能 使 用blob 函 数 对 其 进 行 操 纵。 

 您 所 使 用 的DBMS 中, 怎 样 的 数 据 类 型 可 以 在PowerScript 中 与BLOB
 数 据 类 型 相 对 应 ? 

        这 里 罗 列 的 一 些 常 见 数 据 库 的 数 据 类 型, 其 它 类 型 的 数 据 库 请 查 询 该 数 据
 库 的 相 关 文 档, 及PowerBuilder 的 用 户 手 册。 
  DBMS
                             数 据 类 型 
  Watcom SQL
                             long binary, long varchar 
  Oracle
                             longraw 
  SQL Server
                             Image, Text 
  Informix
                             Text 
  MDI Gateway DB/2
                             Long varchar 
  SQLBase
                             longvarchar 
  AllBase
                             longvarchar 
  DB2/2
                             N/A 


 二、 在 数 据 窗 口 中 使 用OLE 列 

 在 数 据 窗 口 中 使 用OLE 列, 必 须 满 足 以 下 要 求: 

      包 括OLE 列 的 表 必 须: 
      具 有 一 个 可 以 对 应 成 为BLOB 的 数 据 类 型; 
      一 个OLE 列 必 须 允 许 为 空; 
      必 须 有 主 键; 

      如 果 您 使 用 的 开 发 环 境 是SQL Server, 您 必 须 将AUTOCOMMIT 设 置 为TRUE; 
      在 数 据 窗 口 画 笔 中 指 定 数 据 源 的 列 名 时, 存 储BLOB 数 据 的 列 不 能 被 包
      括; 

        在 数 据 窗 口 设 计 时, 选 择 菜 单Ojbect|OLE Database Blob, 然 后 在 设 计 窗 口 上 空
 点 一 下, 这 时 会 出 现 这 样 的 一 个 屏 幕: 

                                                           

        在 这 个 定 义 属 性 的 窗 口 中, 大 部 分 的 内 容 与 定 义 其 它 数 据 窗 口 列 属 性 的 窗
 口 大 致 相 当, 只 有 这 个definition 项 与 其 它 列 不 同, 这 里 特 别 说 明 一 下: 

        上 面 几 项 内 容 的 填 写 较 易 理 解, 事 实 上 只 要 保 留 其 缺 省 值 就 可 以 了。 

        Key Clause: 这 一 项 的 内 容 是PowerBuilder 用 以 确 定 在select 和update 语 句 中 如 何 使
 用WHERE 子 句 的。 一 般 我 们 使 用 这 一 个 表 的 主 键 就 可 以 了。 在 这 个 例 子 里, 就
 相 当 于where 子 句 是"... where id =: id"。 请 注 意 理 解 这 两 个“id” 不 同 的 含 义 和 各 自 的
 指 代。 

        File Template: 用 以 指 定 您 所 希 望 的 这 个OLE 对 象 使 用 的 公 共 模 板。 在 本 列 中,
 我 们 保 留 其 为 空。 但 是 如 果 您 存 储 的 是word 文 件, 您 就 应 当 指 定 一 个DOC 文
 件, 或 者 是normal.dot 文 件 等。 

        OLE Class: Description (Only Class is used) : 如 果 您 没 有 使 用 文 件 模 板, 您 就 应 当 在 这
 里 指 定 一 个 应 用 类, 本 例 中 我 们 使 用PaintBrush。 如 果 您 打 算 使 用 的 应 用 类 并 没
 有 包 括 在 这 个 下 拉 式 列 表 框 中, 您 就 应 当 在Windows 的 注 册 文 件 中 加 入:
 在Windows3.1 中 您 应 当 修 改win.ini 文 件, 而 在Windows95 和Windows NT 中 您 应 当 调
 用REGEDIT 应 用 程 序。 

        Client Name Expression: 这 个 表 达 式 是 用 以 得 到blob 列 中 每 行 的 不 同 值。 这 可 以
 使OLE 对 不 同 的blob 行 引 用 不 同 的 对 象。 

        完 成 了 数 据 窗 口 的 设 计 后, 您 可 以 在 其 设 计 预 览 方 式 下 测 试 这 个OLE 列。
 只 要 在 这 个 对 象 上 双 击,PowerBuilder 就 会 自 动 启 动 服 务 器 应 用, 进 入 一 个 新 文
 件 的 编 辑 和 一 个 模 板 拷 贝 的 编 辑, 这 当 然 要 根 据 您 设 定 的 是 对 象 类 还 是 文 件
 模 板。 为 了 使 这 个OLE 列 更 醒 目, 您 可 以 在 其 背 后 加 入 一 幅 图, 或 加 上 边 框。 

        当 您 确 实 地 在 这 一 列 中 存 储 了 数 据, 在 这 一 列 的 位 置 上 就 会 出 现 一 个 与 您
 所 使 用 的OLE 服 务 器 应 用 相 对 应 的 图 标。 

        对OLE 列 的 更 新 
        OLE 列 只 能 够 在 数 据 窗 口 中 得 以 更 新。OLE 对 象 存 储 在OLE 对 象 容 器(container)
 之 中, 并 为OLE 服 务 器 提 供 信 息 和 它 们 的 类 名。 当 其 中 的 内 容 更 新 时, 这 个 容
 器 必 须 保 留。 这 个 功 能 是 设 计 在 数 据 窗 口 和OLE 列 对 象 之 内 的, 可 是 如 果 您 打
 算 在 数 据 窗 口 之 外 更 新 这 个Blob 对 象, 您 就 将 破 坏 这 个 容 器。 

        使 用OLEActivate 函 数 
        如 果 您 打 算 使 用 程 序 激 活 一 个OLE 列, 而 不 是 等 用 户 双 击 这 个 列, 您 就 可
 以 使 用OLEActivate 函 数。 这 个 函 数 的 语 法 为: 

        datawindowcontrol.OLEActivate ( row, column, verb ) 

        此 外 您 打 算 以 非 零 的“verb” 值 激 活OLE 列, 也 需 要 用 到 这 个 函 数。 关
 于“verb” 值 的 定 义, 是 根 据 不 同 的OLE 服 务 器 而 定 的, 您 必 须 查 询 所 使 用
 的OLE 服 务 器 文 档。 使 用windows95 的 用 户 可 以 用REGEDIT 查 询 注 册 窗 口 的 数 据
 库。 键 入REGEDIT /V 可 以 看 到 整 个 注 册 窗 口 的 树 型 列 表。 

        例 如 我 们 有 一 个 名 为dw_sound 的 数 据 窗 口, 其 中 有 一 个OLE 列 为“sound_blob”
 包 含 的 是.wav 文 件, 我 们 希 望 使 用 微 软 的Quick Recorder 作 为OLE 服 务 器, 我 们 可
 以 这 样 调 用 这 个 函 数 

        dw_sound.OLEActivate(5, "sound_blob", 1) 
        在Quick Recorder 中“verb” 值 为1 表 示 编 辑。 
        又 如: 
        dw_sound.OLEActivate(2, 4, 0) 

        表 示 激 活OLE 服 务 器 调 用 数 据 窗 口 中 第 二 行 第 四 列 的 数 据,“verb” 为0 表 示
 演 奏 这 个.wav 文 件。 

        使 用Sybase 用 户 应 注 意 的 问 题: 

        Sybase 对 于OLE 列 的 控 制 同 其 它 数 据 库 比 有 一 些 小 小 的 限 制, 这 体 现 在Sybase
 的text 数 据 类 型 上。 由 于Sybase 的 字 符 串 函 数 的 作 用, 作 为blob 字 段 的text 数 据 类 型
 最 大 只 能 到4K。 

 三、 不 使 用OLE 方 式 对Blob 进 行 操 作: 

        在PowerScript 中 提 供 给 您 许 多 不 使 用OLE 而 处 理 大 型 二 进 制 大 型 的 方 法。 例
 如 下 例 将 数 据 读 入Blob 列: 

        /* 本 段 代 码 将 读 取 一 个 超 过32766 字 节 的 文 件, 这 个 代 码 可 以 用 以 读 取Text 文
 本 和Bitmap 图 象。*/ 

 SetPointer(HOURGLASS!)
 int li_filenum, li_loops, li_counter long ll_filelen, ll_ll_bytes_read, ll_new_pos 
                      blob lb_ourblob, lb_tot_b
 ll_filelen = FileLength(sle_filename.text)
 // 获 取 文 件 的 大 小
 li_filenum = FileOpen(sle_filename.text,STREAMMODE!,
                       READ!,LOCKREAD!)
 // 指 定 该 文 件 为 只 读,li_filenum 为 这 个 文 件 的 句 柄
 IF ll_filelen > 32766 THEN
         li_loops = ((ll_filelen-1)/32766) + 1
 ELSE
 li_loops = 1
 END IF
 /*FileRead() 函 数 不 支 持 读 取 大 于32K 的 文 本,
               计 算 将 使 用 FileRead 函 数 的 次 数*/
 // 读 文 件...
 FOR li_counter = 1 to li_loops
         ll_bytes_read = FileRead(li_filenum,lb_our_blob )
         lb_tot_b = lb_tot_b + lb_our_blob
         ll_new_pos = ll_new_pos + ll_bytes_read
         FileSeek(li_filenum,ll_new_pos,FROMBEGINNING!)
 NEXT 
 FileClose(li_filenum) 

        // 现 在lb_tot_b 已 包 括 了 文 件 的 内 容, 如 果 这 个 文 件 是 位 图 文 件, 可 对 其 使
 用SetPicture 函 数, 如 果 是 文 本 文 件, 可 使 用string() 函 数 将 其 转 成text 文 件。 
        SetPicture(p_my_picture, lb_tot_b) 

        现 在 您 已 有 了 一 个 存 在blob 变 量 中 的BLOB 数 据, 您 可 以 将 其 写 入 数 据 库 中。
 如 果 您 不 打 算 使 用OLE, 您 可 以 使 用 在PowerScript 中 使
 用SELECTBLOB,UPDATEBLOB 语 句。 同 时, 必 须 满 足 以 下 条 件: 

        1. 您 必 须 在 数 据 库 中 定 义 有 与blob 数 据 类 型 相 等 的 数 据 类 型( 如 在Watcom 中
 的Long Varchar 和Long Binary, 在SQL Server 中 的Image, 在Oracle 中 的long raw 等)。 
        2. 每 一 个 定 义 有blob 字 段 的 表 必 须 有 主 键。 
        3. blob 列 必 须 允 许 为 空。 
        4. 您 打 算 写 入blob 数 据 的 这 一 条 记 录 必 须 已 经 输 入 数 据, 也 就 是 说 您 只 能 使
 用UPDATE 的 方 式 写 入blob 数 据。 
        5. SQL SERVER 的 用 户 必 须 在 使 用BLOB 功 能 前 将AUTOCOMMIT 设 置 为TRUE,
 在BLOB 功 能 结 束 后 可 再 恢 复 回FALSE 状 态。 可 是 有 关BLOB 的 功 能 却 不 能 同 其 它
 操 作 在 同 一 个 事 物 之 中。 

        例 如 我 们 在Watcom 数 据 库 中 有 一 个 称 作blob_table 的 表 其 中 有 两 个 字 段 分 别
 为blob_id, 整 型, 主 键;blob_col 数 据 类 型 为long binary 并 且 将 其 设 置 为 允 许 为 空。
 在 我 们 将blob 写 入 数 据 库 之 前, 我 们 必 须 将 主 键 的 值 写 入 数 据 库。 我 们 在 表 中
 加 入 一 个 新 记 录,blob_id 的 值 为373, 而blob_col 设 置 为NULL。 然 后 我 们 执 行 下 面
 的 代 码: 

 UPDATEBLOB blob_table SET blob_col = :lb_tot_b 
             WHERE blob_id = 373 USING SQLCA;
 IF sqlca.sqlcode < > 0 then
         messagebox("UPDATEBLOB 失 败", sqlca.sqlerrtext)
 END IF

        与UPDATEBLOB 相 对 应 的 是SELECTBLOB, 使 用SELECTBLOB 同 使 用SELECT INTO
 语 句 基 本 相 同, 只 是 这 时 我 们 操 纵 的 是BLOB 数 据 类 型 而 已。 例 如: 

 blob lb_blob_var
 SELECTBLOB blob_col INTO :lb_blob_var FROM blob_test 
        WHERE blob_id = 423  USING SQLCA; 

        现 在 您 就 可 以 通 过Powerscript 操 纵 得 到 的blob 变 量 了。 

        注 意: 您 可 以 使 用UPDATEBLOB 语 句 修 改 多 条 记 录, 使 这 些 记 录 具 有 相 同 的
 值, 但 是 您 却 不 能 使 用SELECTBLOB 语 句 得 到 多 于 一 条 的 记 录。 您 必 须 使
 用WHERE 条 件 确 保SELECTBLOB 查 询 到 的 是 一 行 记 录。 
        您 也 可 以 将 从 数 据 库 读 出 的blob 数 据 写 入 本 地 的 文 件 中, 方 法 与 读 文 件 相
 似。 

 四 其 它Blob 字 段 的 函 数 

        此 外PowerBuilder 还 提 供 了 其 它 三 个 有 关 对Blob 函 数 的 操 作: Blob(), BlobEdit() and
 BlobMid()。 这 几 个 函 数 的 使 用 您 可 以 查 询 有 关 的 文 档。 

                       


--
※ 来源:.紫 丁 香 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)
页面执行时间:208.913毫秒