数据窗口更新问题

smilegw 2003-08-22 08:37:04
我的一个数据窗口中,连接了三个表中的字段,点保存的时候,将这三个表中的数据同时更新,请问大家如何实现?
...全文
150 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
Key 2003-09-15
  • 打赏
  • 举报
回复
最近很忙,所以少来!!抱歉!!回答晚了!
Key 2003-09-15
  • 打赏
  • 举报
回复
现在,我建立了一个数据窗口,涉及到两个表,比如 A 表,和B表,两个表之间用一个外键连接,B表的主键是A表的外键!
在数据窗口更新的时候,由于我是建立一个新的记录,并且要对两个表都要写,因此,在数据窗口的更新属性中,我设置为更新A表。更新的字段为 a.id、a.name……,在更新成功的情况下,修改数据窗口的更新属性,变为B表更新,并修改相应的字段更新属性。

代码示意如下:
初始数据窗口更新属性为 A 表,更新字段为A表的所有字段。

……
long rtcode
rtcode = dw_1.update(true,false)
if rtcode = 1 then //更新第一个表成功

dw_1.modify("a_id.update = 'No'") //修改第一个表的字段更新属性为不更新
dw_1.modify("a_name.update = 'No'"
dw_1.modify("a_id.key = 'no'))
……
//修改第二个表的更新属性为可更新
dw_1.modify("datawindow.Table.updatetable = 'B'")
dw_1.modify("b_id.update = 'yes'")
dw_1.modify("b_name.update = 'yes')
dw_1.modify("b_id.key = 'yes')
……
if dw_1.update() = 1 then //更新第二个表成功
COMMIT;
else
messagebox("错误", "提交不成功")
end if

end if
Key 2003-08-22
  • 打赏
  • 举报
回复
我现在也正在为这个问题发愁!!

在一个数据窗口中,更新数据只能每次更新一个表,然后在提交的时候可以这样,dw_1.update(True, false) ,第一个True表示自动更新字段,第二个false标识并没有将更新数据提交到数据库中,只是在缓冲区中。
然后,使用 dw_1.modify("a_colunm1.update = false")
……
dw_1.modify("datawindow.table.updatetable = 'Table_b'")来改变更新的表
dw_1.modify("b_column1.update = true")
……
再次更新,dw_1.update(true,false)
直到最后的一个表的 dw_1.update()返回值也是1,然后提交 COMMIT;否则,ROLLBACK;这样前面的表也不会向数据库中更新,这样就可以实现了多个表的同时更新。

flyerlxg 2003-08-22
  • 打赏
  • 举报
回复
用视图怎样?
smilegw 2003-08-22
  • 打赏
  • 举报
回复
可没办法的,我的数据窗口必须得从三个表中取数据,保存的时候也必须同时保存的!
sundayblue 2003-08-22
  • 打赏
  • 举报
回复
更新表只能是一个一个进行,所以你只能选择一个表,你可以先选中一个表,设为可更新,更新完了之后再让另外一个表为可更新表,当然这必须代码控制了(用modify函数),建议你不要用三个表一块更新,代码写起来很麻烦。
smilegw 2003-08-22
  • 打赏
  • 举报
回复
可是在数据窗口中的update属性中只能选择一个表!怎么才将三个表中的主键全选中呀?
klbt 2003-08-22
  • 打赏
  • 举报
回复
可以做到,前提是你要选择三个表的主键。
szpqq 2003-08-22
  • 打赏
  • 举报
回复
如果能确定是增加修改或删除的话,用sql语句更新也可以,直接写,另外你可以找找多表更新的方法很多的,先是更新一表,然后再更换!
smilegw 2003-08-22
  • 打赏
  • 举报
回复
lyqq(紫钥)
能再具体些吗?
wangbangc 2003-08-22
  • 打赏
  • 举报
回复
先更新一个表,然后把焦点给到下一个表,更新此表
Key 2003-08-22
  • 打赏
  • 举报
回复
我的问题已经搞定了,就是,楼上我说得样子。

其中,要注意的问题是
dw_1.modify()中的字符串要注意自己的问题,不要拼写错误,我的错误就都是拼写错误引起的,主要是因为,在字符串出现错误的时候,系统并不会提示出现问题,而是直接通过,不起作用而已!!
smilegw 2003-08-22
  • 打赏
  • 举报
回复
刚刚在网上找到一种方法,拿出来给大家看一下!
            
               实现PB数据窗口的多表更新


  PowerBuilder的数据窗口对象是其特有的智能对象,其封装性好、功能强大、表现形式丰富多样,为此,许多MIS开发人员对PowerBuilder推崇备至,将其视为首选开发工具。

  一般情况下,一个数据窗口只能更新一个数据库表,但在MIS开发过程中,我们经常遇到这种情况:一个数据窗口中由两个或更多个数据库表作为数据源,并需要对其进行录入或修改,如何给出多表更新的通用解决方案就成为MIS开发人员不容回避的问题。笔者在某管理信息系统的开发过程中,尝试了几种双表更新的解决方法,选出一种比较好的方案,以飨读者。

  一、具体步骤
  1. 在数据窗口建立时,选择SQL Select,显示风格可以是Tabular、Grid或FreeForm中的任一种。选出两表需要录入或修改的列,其中两表的主键和非空列必须选中,确定选择条件,建立连接关系。
  2. 在选单“Rows/Update”中选择第一个表的全部数据项为可更新项。
  3. 把两表需要修改项的Tab Order数值改为非0值,使其在数据窗口中成为可修改项。
  为了使方案具有通用性,建立全局函数f_update_2table,有五个参数:dw_obj、table1、table2、key1、key2,分别代表所要更新的数据窗口、两表表名和两表主键列名,其中dw_obj为DataWindow类型,其余四参数均为String类型。该函数返回值为Boolean型,返回True表示成功,返回False表示失败。

  二、函数思路

  1. 先针对第一个数据库表调用Update函数更新。注意参数的使用:第一个参数作用是控制数据窗口更新前是否强制性调用AcceptText(),在数据窗口更新前通过有效性验证;第二个参数是控制更新标志的复位,为True时更新标志复位,为False时更新标志不复位。
  2. 更改数据窗口的UpdateTable属性,使其指向第二个表,并把第一个表的各数据项Update属性和主键列的Key属性改为No,接着把第二个表的各数据项Update属性和主键列的Key属性改为Yes。
  3. 调用Update函数更新第二个表。
  4. 两表更新成功后,把两表的列属性、主键属性改回到初始状态,以便为下一次的两表更新调用做好准备。
  三、程序清单
  // ColName:数据窗口列名
  // Name1[],Name2[]:两数据库表选中项列名
  // n1,n2:两数据库表选中项数量
  // i:循环计数器
  // Columns:数据窗口总列数
  String ColName,Name1[],Name2[]
  Integer Columns,i,n1=0,n2=0
  //下面程序:找出dw_obj的两表列名赋给Name1[],Name2[]
  Columns=Integer(dw_obj.Describe(″DataWindow.Column.Count″))
  FOR i=1 TO columns
ColName=Upper(dw_obj.Describe(″#″+String(i)+″.Name″))
IF Left(ColName,Len(Table1))=Table1 and ColName〈〉Key1 THEN
n1=n1+1
Name1[n1]=ColName
END IF
IF Left(ColName,Len(Table2))=Table2 and ColName〈〉Key2 THEN
n2=n2+1
Name2[n2]=ColName
END IF
NEXT

  // 下面程序:存储dw_obj,确定返回值(True:成功,False:失败)
  IF dw_obj.Update(True,False)=1 THEN
   FOR i=1 TO n1
   dw_obj.Modify(Name1[i]+″.Update=No″)
   NEXT
dw_obj.Modify(Key1+″.Key=No″)
  dw_obj.Modify(″DataWindow.Table.Update
  Table=′ ″+Table2+″ ′ ″)
FOR i=1 TO n2
  dw_obj.Modify(Name2[i]+″.Update=Yes″)
NEXT
   dw_obj.Modify(Key2+″.Key=Yes″)
IF dw_obj.Update()=1 THEN
Commit;
FOR i=1 TO n1
dw_obj.Modify(Name1[i]+″.Update=Yes″)
NEXT
dw_obj.Modify(Key1+″.Key=Yes″)
dw_obj.Modify(″DataWindow.Table.UpdateTable=′ ″+Table1+″ ′ ″)
FOR i=1 TO n2
dw_obj.Modify(Name2[i]+″.Update=No″)
NEXT
dw_obj.Modify(Key2+″.Key=No″)
return True
ELSE
Rollback;
return False
END IF
  ELSE
Rollback;
return False
  END IF
  四、调用方法
  假设窗口名为w_update,数据窗口为dw_1,数据库表名和主键名分别为t1、t2、k1、k2,放置“存盘”按钮,按钮Clicked事件的Script语句如下:
  dw_1.AcceptText()
  IF dw_1.ModifiedCount()〉0 or dw_1.DeletedCount()〉0 THEN
IF MessageBox(″提示信息″,″是否存盘?″,Question!,YesNo!)=1 THEN
   IF f_update_2table(dw_1,″t1″,″t2″,″k1″,″k2″) THEN
   Commit;
ELSE
Rollback;
   END IF
   END IF
  END IF
  综上所述,可以看出,该方案具有很好的可扩展性,稍加修改即可解决多表作为数据源的数据窗口的同步更新问题。

smilegw 2003-08-22
  • 打赏
  • 举报
回复
刚刚在网上找到一种方法,还没有用呢,现拿出来供大家参考


实现PB数据窗口的多表更新
  PowerBuilder的数据窗口对象是其特有的智能对象,其封装性好、功能强大、表现形式丰富多样,为此,许多MIS开发人员对PowerBuilder推崇备至,将其视为首选开发工具。

  一般情况下,一个数据窗口只能更新一个数据库表,但在MIS开发过程中,我们经常遇到这种情况:一个数据窗口中由两个或更多个数据库表作为数据源,并需要对其进行录入或修改,如何给出多表更新的通用解决方案就成为MIS开发人员不容回避的问题。笔者在某管理信息系统的开发过程中,尝试了几种双表更新的解决方法,选出一种比较好的方案,以飨读者。

  一、具体步骤
  1. 在数据窗口建立时,选择SQL Select,显示风格可以是Tabular、Grid或FreeForm中的任一种。选出两表需要录入或修改的列,其中两表的主键和非空列必须选中,确定选择条件,建立连接关系。
  2. 在选单“Rows/Update”中选择第一个表的全部数据项为可更新项。
  3. 把两表需要修改项的Tab Order数值改为非0值,使其在数据窗口中成为可修改项。
  为了使方案具有通用性,建立全局函数f_update_2table,有五个参数:dw_obj、table1、table2、key1、key2,分别代表所要更新的数据窗口、两表表名和两表主键列名,其中dw_obj为DataWindow类型,其余四参数均为String类型。该函数返回值为Boolean型,返回True表示成功,返回False表示失败。

  二、函数思路

  1. 先针对第一个数据库表调用Update函数更新。注意参数的使用:第一个参数作用是控制数据窗口更新前是否强制性调用AcceptText(),在数据窗口更新前通过有效性验证;第二个参数是控制更新标志的复位,为True时更新标志复位,为False时更新标志不复位。
  2. 更改数据窗口的UpdateTable属性,使其指向第二个表,并把第一个表的各数据项Update属性和主键列的Key属性改为No,接着把第二个表的各数据项Update属性和主键列的Key属性改为Yes。
  3. 调用Update函数更新第二个表。
  4. 两表更新成功后,把两表的列属性、主键属性改回到初始状态,以便为下一次的两表更新调用做好准备。
  三、程序清单
  // ColName:数据窗口列名
  // Name1[],Name2[]:两数据库表选中项列名
  // n1,n2:两数据库表选中项数量
  // i:循环计数器
  // Columns:数据窗口总列数
  String ColName,Name1[],Name2[]
  Integer Columns,i,n1=0,n2=0
  //下面程序:找出dw_obj的两表列名赋给Name1[],Name2[]
  Columns=Integer(dw_obj.Describe(″DataWindow.Column.Count″))
  FOR i=1 TO columns
ColName=Upper(dw_obj.Describe(″#″+String(i)+″.Name″))
IF Left(ColName,Len(Table1))=Table1 and ColName〈〉Key1 THEN
n1=n1+1
Name1[n1]=ColName
END IF
IF Left(ColName,Len(Table2))=Table2 and ColName〈〉Key2 THEN
n2=n2+1
Name2[n2]=ColName
END IF
NEXT

  // 下面程序:存储dw_obj,确定返回值(True:成功,False:失败)
  IF dw_obj.Update(True,False)=1 THEN
   FOR i=1 TO n1
   dw_obj.Modify(Name1[i]+″.Update=No″)
   NEXT
dw_obj.Modify(Key1+″.Key=No″)
  dw_obj.Modify(″DataWindow.Table.Update
  Table=′ ″+Table2+″ ′ ″)
FOR i=1 TO n2
  dw_obj.Modify(Name2[i]+″.Update=Yes″)
NEXT
   dw_obj.Modify(Key2+″.Key=Yes″)
IF dw_obj.Update()=1 THEN
Commit;
FOR i=1 TO n1
dw_obj.Modify(Name1[i]+″.Update=Yes″)
NEXT
dw_obj.Modify(Key1+″.Key=Yes″)
dw_obj.Modify(″DataWindow.Table.UpdateTable=′ ″+Table1+″ ′ ″)
FOR i=1 TO n2
dw_obj.Modify(Name2[i]+″.Update=No″)
NEXT
dw_obj.Modify(Key2+″.Key=No″)
return True
ELSE
Rollback;
return False
END IF
  ELSE
Rollback;
return False
  END IF
  四、调用方法
  假设窗口名为w_update,数据窗口为dw_1,数据库表名和主键名分别为t1、t2、k1、k2,放置“存盘”按钮,按钮Clicked事件的Script语句如下:
  dw_1.AcceptText()
  IF dw_1.ModifiedCount()〉0 or dw_1.DeletedCount()〉0 THEN
IF MessageBox(″提示信息″,″是否存盘?″,Question!,YesNo!)=1 THEN
   IF f_update_2table(dw_1,″t1″,″t2″,″k1″,″k2″) THEN
   Commit;
ELSE
Rollback;
   END IF
   END IF
  END IF
  综上所述,可以看出,该方案具有很好的可扩展性,稍加修改即可解决多表作为数据源的数据窗口的同步更新问题。

coordinate 2003-08-22
  • 打赏
  • 举报
回复
只有像lyqq(紫钥) 那样做
smilegw 2003-08-22
  • 打赏
  • 举报
回复
难道就没有更好的方法了吗?我想这是个很普遍的问题吧,人人都会遇到的,你们是怎么解决的呀??

609

社区成员

发帖
与我相关
我的任务
社区描述
PowerBuilder DataWindow
社区管理员
  • DataWindow社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧