---- 在 开 发 中, 我 们 有 时 会 遇 到 用 一 个DataWindow 来 表 现 数 据 库 中 多 个 表 中 数 据 的 情 形, 这 时DataWindow 用 到 的SQLSelect 语 句 是 一 个 多 张 表 连 接 的 视 图。 当 我 们 对 这 样 一 个DataWindow 中 的 数 据 进 行 修 改 并 提 交 数 据 库 时, 我 们 将 会 发 现 我 们 并 不 能 简 单 地 使 用 一 条dw.update() 来 实 现 同 时 对 数 据 库 中 多 张 表 的 修 改。
---- 事 实 上, 系 统 在DataWindow 中 提 交 数 据 库 并 生 成UPDATE 语 句 时 所 根 据 的 仍 然 是 图 一 这 个 窗 口。 在 以 前 的 章 节 中 我 们 曾 介 绍 过 利 用 这 个 窗 口 中 一 些 不 同 的 选 项 实 现 数 据 库 的 并 发 控 制, 这 里 我 们 再 讲 一 下 这 个 窗 口 中 的 选 项 对 生 成UPDATE 语 句 的 其 它 影 响。
---- 当 我 们 调 用UPDATE
函 数 时, 这 个 窗 口 中 有 四 个 域 将 被 涉 及:
---- 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
---- 调 用 这 一 函 数
时 应 遵 守 以 下 规 则:
---- 在 上 例 中, 我 们
可 以 这 样 调 用 这 个 函 数
f-MUpdate(dw-l," dbo.sales-order") f-MUpdate(dw-l," dbo.customer")