起步软件技术论坛-X3

 找回密码
 立即注册
搜索
查看: 399|回复: 11

如何同时打开多张TSQlDataSet

[复制链接]
发表于 2009-8-31 14:56:11 | 显示全部楼层 |阅读模式
由于有的业务比较复杂,最多包含30多张表。由于应用的需求,这些表都需要打开(使用代码Open),虽然每张表打开速度比较快,但是30多个表和起来就慢的让人接受不了了。

能否一次 IO 交互就打开所有表?我们测试过,使用线程打开Tinfo上的TSQLDataSet,但是线程会死锁。尝试线程中使用TQuery取回数据后将Data传给TSQLDataSet,但是线程打开TQuery不稳定,有时会失败。

平台现有的资源能否实现我们的这个需求呢,殷切盼望答复。
回复

使用道具 举报

发表于 2009-8-31 15:09:53 | 显示全部楼层
能说下怎么设计的,非要30张表同时打开?
回复 支持 反对

使用道具 举报

发表于 2009-8-31 15:11:59 | 显示全部楼层
线程跟打开速度无关,不用考虑这个问题。
解决根源在于你的30个表同时打开。
必须要分步打开表,否则客户肯定会感觉非常的慢。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-8-31 15:22:19 | 显示全部楼层
比如字段只读、可见性、TAction的可用性,依赖于任意表的任意字段。不打开表,就无法计算这些表达式
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-8-31 15:34:21 | 显示全部楼层
线程可以解决部分问题,例如 各类任务数量的查询,显示在桌面面板上。统计5类任务的数量,依次执行的时间较长,面板显示速度就慢。使用线程,可以有效缩短这部分时间。

未知原因,有时候这5个线程中某一个线程的执行会失败.

procedure TAsynQueryThread.Execute;
begin
  Synchronize(DoQuery);
end;

procedure TAsynQueryThread.DoQuery;
begin
  try
    FQuery.Open;
    FSucceed := True;
  except
    FSucceed := False;
  end;
end;

(FQuery外部传入,没有任何数据集事件,无关联感知组件)有时候Synchronize 会报异常.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-8-31 15:42:13 | 显示全部楼层
TCMDBatchCall、TCMDGetRecords能否实现一次IO返回多个数据集的数据呢?
回复 支持 反对

使用道具 举报

发表于 2009-8-31 16:34:15 | 显示全部楼层
写程序从原则上来讲,无论如何也不应该打开30多张表的,就算必须打开,也要通过修改业务设计来避免的,因为既然可能打开30多张自然也会打开300,3000,30000张这样的需求是不太可能完成的,至于怎么修改设计就跟业务需求密切相关了,但有一点那就是这种无论如何都要避免的。因为那样就算系统能支持返回,在内存有限,网络状况有限,如果硬要实现这种需求也是很难受的,数据库自己也不支持一次打开N张表返回的。

一般建议表分梯次打开。一次只打开几个,其它的按需要打开。

特别是楼主说的TAction的Eanbled,字段只读无论如何都不应该每次去打开数据集判断的,建议楼主采用当前数据表中增加冗余数据或其它的方式解决问题!如果一时想不到解决方案,可以把业务大概举几个场景描述一下,大家共同想想办法。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-8-31 19:25:47 | 显示全部楼层
有一点可以肯定,虽然30张表,但是每张表只会返回1条记录,数据量也就当量于30条记录。至于为什么这么建模,有历史原因;还有就是一个审批过程涉及几百字段,就把这些字段按一定类型拆分到不同表里。
回复 支持 反对

使用道具 举报

发表于 2009-9-1 09:11:45 | 显示全部楼层
哦?明白了,但系统确实无法支持一次打开30张表,看能否想点招儿在SQL上做手脚,让这三十条记录合并到一条记录(一个数据集)里返回。因为你反回一条记录也不会用户这条记录的N多字段吧,一般用一两个字段也就够了!
回复 支持 反对

使用道具 举报

发表于 2009-9-1 09:31:46 | 显示全部楼层
可以类似于这样写,把记录集中到一条记录上
SELECT FGUID, FID, (SELECT FKIND FROM TORGSYSTEM WHERE FGUID = 'C61BDD74FD3641A09AB3058571CFD693'), (SELECT FID FROM TDEPT
WHERE FGUID = '1AED2DDCA581465B952E85A634D3DE90'), (SELECT FID FROM TFileSystem where FGUID = '00025BDFA4024493B30ED77B131EA462')

FROM TPERSON WHERE FGUID = '806525315AD44A5E89455F734506D5FC'

也可以利用Union
select FGUID from TPERSON UNION SELECT convert(varchar, FDELETELEVEL) FROM TOrgsystem

把所需要的东西集中到一个记录集中返回。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Justep Inc.

GMT+8, 2025-7-17 03:42 , Processed in 0.045359 second(s), 16 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表