精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● Powerbuilder>>锦上添花 技巧大家谈>>取大量数据的一个方法

主题:取大量数据的一个方法
发信人: fanpb()
整理人: flyingmist(2000-03-05 20:20:11), 站内信件
原因:
   一个ORACLE数据库因使用者操作失误导致一个数据文件损坏,将该
文件设置为OFFLINE,数据库可以启动。但有许多表部份损坏。也就是
不能访问某一范围记录。为了减少损失,设法取出所有能够查到的数据。
   用存储过程或PL/SQL将数据复制到另一个Database不行。似乎是PL/SQL
在编译时要检查表的状态,发现不能全部读取就报错,根本不能运行。

   最后只能用PB将这些记录select retrieve到本地,并保存为文件,
重装数据库后再图恢复。但因数据量太大,各别表有上百万条记录,
一次Retrieve内存肯定不够,后经再三试验找到一个方法供参考。

方法:
   在一个窗口上放两个datawindow,分别命名为dw_1 和dw_2,不要指定
任何datawindow object。 并且setredraw(false)。
   在script中:
   合成字符串 "select * from 表",然后
   用sqlca.syntaxfromsql创建dw语法,然后分别调用 dw_1.create和
   dw_2.create。
   dw_1.settransobject(sqlca)。

   关键技术:
   在dw_1.retrieverow事件中,检查dw_1.rowcount()为一个规定数量,
如1000条记录时,将dw_1.saveas(),然后dw_1的所有记录用rowsmove
函数移动到dw_2中,然后dw_2.reset()。
   dw_1.retrieveend事件中,如果rowcount()>0如法炮制。

   rowsmove的目的是为了清空dw_1所占用的内存,而dw_2.reset清dw_2
占用的内存。
   实际结果是运行了一个晚上,取出了100多万条记录,在硬盘上存了500多
M的文本文件,而没有出现任何内存问题。

   不对的做法:当dw_1.rowcount()达到1000条记录时,用deleterow删
除,这样做没用,因为deleterow不会释放内存。

其它用途:
   这个做法实际上有些其它的用途,特别适用于异种数据库之间的数据转换。

如oracle->sql anywhere ,oracle->sql server,只要略加改造,建立两个
数据库联接sqlca和sqlca1,dw_2使用sqlca1,将move到dw_2的数据update ,
就实现了数据的传递。当然可以用pipe-line完成表的转换,但这样做的另
一个好处是dw_1可以不是一个表,如一个 sum-group 语句,总之在比较复杂
的情况下可以使用这种技术,分段处理,无内存之忧。

改进:如果用一个uo封装,将datawindow改为datastore派生的对象,就是一个

非常灵活好用的控件了,哪位大侠开发了别忘给我一份,先谢过了。

--
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.106.4.9]

[关闭][返回]