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毫秒