Database 版 (精华区)

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

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


 ---- 在 开 发 中, 我 们 有 时 会 遇 到 用 一 个DataWindow 来 表 现 数 据 库 中 多 个 表 中
 数 据 的 情 形, 这 时DataWindow 用 到 的SQLSelect 语 句 是 一 个 多 张 表 连 接 的 视
 图。 当 我 们 对 这 样 一 个DataWindow 中 的 数 据 进 行 修 改 并 提 交 数 据 库 时, 我
 们 将 会 发 现 我 们 并 不 能 简 单 地 使 用 一 条dw.update() 来 实 现 同 时 对 数 据 库 中
 多 张 表 的 修 改。 

 ---- 事 实 上, 系 统 在DataWindow 中 提 交 数 据 库 并 生 成UPDATE 语 句 时 所 根 据 的
 仍 然 是 图 一 这 个 窗 口。 在 以 前 的 章 节 中 我 们 曾 介 绍 过 利 用 这 个 窗 口 中 一
 些 不 同 的 选 项 实 现 数 据 库 的 并 发 控 制, 这 里 我 们 再 讲 一 下 这 个 窗 口 中 的
 选 项 对 生 成UPDATE 语 句 的 其 它 影 响。 

 ---- 当 我 们 调 用UPDATE 函 数 时, 这 个 窗 口 中 有 四 个 域 将 被 涉 及: 

      Where Clause for Update/Delete where 子 句 的 生 成 依 据。 这 个 选 项 主 要 是 用 来
      进 行 并 发 控 制 的, 这 里 不 再 赘 述。 
      UpdateableColumns 可 修 改 的 列。 这 是 一 个 我 们 将 遇 到 麻 烦 的 地
      方。PowerBuilder 只 能 同 时 对 一 张 要 修 改 的 表 进 行 管 理, 所 以 我 们 不 能
      一 下 子 指 出 所 有 表 中 所 有 要 修 改 的 列。 在 这 里 我 们 只 能 指 出 某 一 张
      表 中 要 修 改 的 列, 以 后 在 程 序 中 用Modify 语 句 依 次 指 定 其 它 每 一 张 表
      中 要 修 改 的 列。 
      Table to Update 将 要 修 改 的 表。PowerBuilder 只 支 持 一 张 表 的 修 改, 所 以 我
      们 也 只 能 在 这 里 只 指 定 其 中 的 某 一 张 表, 其 余 的 表 也 将 要 利 用Modify
      语 句 修 改。 
      Unique Key Columns 唯 一 键 的 列。 这 也 是 我 们 要 注 意 的 地 方, 因
      为PowerBuilder 生 成 的UPDATE 语 句 只 是 在 要 修 改 的 表 名 中 使
      用DATABASE.OWNER.TABLE 这 样 的 全 称, 而 引 用 某 列 时 只 是 简 单 指 出 列
      名, 而 不 用DATABASE.OWNER.TABLE.COLUMN 这 样 的 全 称。 所 以, 如 果 我
      们 这 里 用 到 的 唯 一 列 标 识 不 属 于 上 面"Table to Update" 中 定 义 的 表 的 列,
      这 一 条SQL 语 句 将 出 现 语 法 错 误。 

 ---- PowerBuilder 在DataWindow 中 产 生 的UPDATE 语 句 和DELETE 语 句 如 下: 
 ---- ●UPDATE database.owner.table 
 ---- SET column=somevalue, 
 ---- WHERE UniqueKeyColumn=somevalue; 

 ---- ●DELETE FROM database.owner.table 
 ---- WHERE UniqueKeyColumn=somevalue; 

 ---- 在 一 条SQLUPDATE 和DELETE 语 句 中, 所 有 引 用 的 列 名 均 不 使 用 列 的 全
 称, 因 此 对 列 名 的 确 定 完 全 由update table 来 决 定, 在UPDATE 语 句 中 所 有 修 改
 属 性 均 设 为TRUE, 而 且 用 户 进 行 过 修 改 的 列 都 将 加 到SET 子 句
 中。PowerBuilder 根 据 用 户 对"Where Clause for Update/Delete" 的 选 择 形 成WHERE 子
 句, 由 于 系 统 自 动 地 将 多 个 表 中 所 有 的 列 都 加 到SET 子 句 和WHERE 子 句 中,
 而PowerBuilder 又 是 根 据 用 户 指 定 的update table 来 确 定 列, 因 此 我 们 显 然 是 无
 法 得 到 一 个 准 确 的SQL 语 句 的。 我 们 来 看 这 样 一 个 实 例( 本 表 可 以
 在PowerBuilderDEOM 数 据 库 中 得 到, 注 意: 如 果 我 们 希 望 某 一 列 不 被 修 改, 我 们
 可 以 在DataWindow 画 笔 中 将TABorder 设 置 为0): 

  CUSTOMER.Customer-ID=101 
  CUSTOMER.FirstName=Michaels 
  CUSTOMER.LastName=Devlin 
  CUSTOMER.Address=3114 Pioneer Avenue 
  SALES-ORDER.ID=2001 
  SALES-ORDER.order-date=09/14/94 
  我 们 将 其 改 为: 
  CUSTOMER.Address=1905 Maple Avenue 
  SALES-ORDER.order-date=12/11/94 

 ---- 如 果 我 们 只 是 用dw.update() 语 句 来 形 成UPDATE 语 句,PowerBuilder 将 自 动 构
 造 成 这 样 的 一 条 语 句: 

 ---- 上 述 三 条SQL 语 句 在 提 交 数 据 库 时 都 将 产 生"Invalid column name ‘id' " 的 错
 误, 很 明 显,"id" 这 一 个 字 段 并 不 在custumer 这 一 张 表 中。 此 外SALES-ORDER 这
 张 表 的 内 容 并 没 有 进 行 修 改。 

 ---- 为 真 正 实 现 对 多 表 数 据 的 修 改, 我 们 可 以 编 写 这 样 一 个 函
 数f-MUpdate()。 

  integer f-MUpdate(a-dw,as-update-table) 
  a-dw-DataWindow 名 称;as-update-table- 将 要 修 改 的 表 名 的 全 称。 
  Long ll-ipos,ll-maxcol,i 
  String ls-colnam,ls-mod,ls-table-name,ls-err,ls-updatekeyll,ls-qualifier="" 
  // 从 传 递 的 参 数 中 分 离 出 表 名 和 域 名 
  ll-ipos=Pos(as-update-table," ·",l) 
  If(ll-ipos >0)Then 
  ls-qualifier =Left(as-update-table,ll-ipos) 
  as-update-table=Mid(as-update-table,& ll-ipos+1) 
  ll-ipos=Pos(as-update-table," ·",l) 
  If(ll-ipos >0)Then 
  ls-qualifier=ls-qualifier+& 
  Left(as-update-table,ll-ipos) 
  as-update-table=Mid(as-update-table,& ll-ipos+1) 
  end If 
  End If 
  // 得 到 这 个DataWindow 包 含 列 的 数 量 

  ls-err=a-dw.object.DataWindow.Column.Count 
  ll-maxcol=Integer(Is-err) 
  If(ll-maxcol <1)Then 
  Return 1 

  End IF 

 ---- // 确 认DataWindow 中 的 每 一 列 是 否 属 于 要 修 改 的 表 中 的 列, 如 是 将
 其update 属 性 设 为 Yes, 否 则 为No. 

  FOR i=1 To ll-maxcol 

  ls-mod="#"+String(i)+".Name" 
  ls-colnam=a-dw.Descibe(ls-mod) 
  ls-table-name=a-dw.Descibe(ls-colnam+&".dbName") 
  ls-table-name=Left(ls-table-name,&) 
  (Pos(ls-table-name," ·",l)-l)) 

  If(Upper(as-update-table)=Upper(ls-table-name))Then 
  ls-mod=ls-colnam+".Update=Yes" 
  Else 
  // 如 果 该 列 不 在 可 修 改 的 表 中, 
  // 而 其 为 主 键 的 属 性 为TRUE 
  // 将 其 列 名 存 在ls-updatekey[ ] 中 
  // 并 将 其 主 键 的 属 性 设 为FALSE。 
  // 由 于PB 不 保 留 列 的 全 名, 我 们 不 能。 
 // 保 留 非 修 改 表 的 键 的 名 称。 
 // 所 以 我 们 将 其 保 留 在 数 组 之 中, 以 便 其 恢 复 
  If(Upper(a-dw.Descibe(ls-colnam+".Key"))=" YES")Then 
  ls-updatekey[UpperBound(ls-updatekey[ ])+1]=ls-colnam 
  ls-mod=ls-colnam+".Key=No" 
  If(a-dw.Modify(ls-mod) < >"")Then 
  Return-2 
  End If 
  End If 
  ls-mod=ls-colnam+".Update=No" 
  End IF 

  // 确 认 修 改 是 否 成 功 
  If(a-dw.Modify(ls-mod) < >"")Then 
 Return-2 
  End IF 

  NEXT 

  // 将 修 改 表 名 设 置 为 全 称 
  a-dw.object.Data Window.Table.UpdateTable=ls-qualifier+as-update-table 

  // 修 改DataWindow 

  If(a-dw.Update(TRUE,FALSE) < >1)Then 
 Return-5 
  Else 
  // 将DataWindow 恢 复 为 其 原 来 的 状 态 
  ll-maxcol=UpperBound(ls-updatekey) 
  FOR i=l to ll-maxcol 
  ls-mod=ls-updatekey[i]+".key=Yes" 
  If(a-dw.Modify(ls-mod) < >"")Then 
 Return-6 
  End If 
  Return 0 
  End If 

 ---- 调 用 这 一 函 数 时 应 遵 守 以 下 规 则: 

      保 证 数 据 的 参 照 完 整 性, 应 当 先 修 改 父 表 后 修 改 子 表; 
      在DataWindow 画 笔 中 为 每 张 表 建 立 唯 一 主 键; 
      在 图 一 窗 口 中, 将 该DataWindow 设 为 允 许 修 改; 
      指 定 所 涉 及 的 任 意 一 张 表 为 修 改 表, 表 中 的 任 一 列 为 可 修 改 列。 以 保
      证DataWindow 有 修 改 权, 这 样 我 们 调 用 的 函 数 就 可 以 覆 盖 这 一 设 置。 
      不 要 将 并 发 控 制 选 为key and > 


      传输中断!

      数 无 法 在 这 一 条 件 下 工 作。 
      将 表 名 的 全 称DATABASE.OWNER.TABLE 传 递 给 这 个 函 数, 特 别 是 在 这
      个DataWindows 是 对 多 个 数 据 库 进 行 操 作 时。 

 ---- 在 上 例 中, 我 们 可 以 这 样 调 用 这 个 函 数 

  f-MUpdate(dw-l," dbo.sales-order") 
  f-MUpdate(dw-l," dbo.customer") 

                       




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