【问题标题】:Master/Detail datasets too many requests主/详细数据集请求过多
【发布时间】:2018-03-05 17:45:33
【问题描述】:

我们有一个 Delphi 应用程序,它使用 Master/Detail 关系中的 ADO 数据集。它们连接到位于另一台服务器上的 SQL Server 数据库。

由于许多详细数据集在打开时会发出大量 SQL 请求,因此应用程序在网络连接速度较慢时速度较慢。有没有办法批量发出所有详细数据集请求?

或者除了 ADO 之外有没有可以更好地处理这种情况的数据集?

【问题讨论】:

  • 首先,这不是主从相关数据集对象的行为方式。当请求 master 时,他们应该查询详细信息。所以你说在你的情况下所有主记录都要求详细信息?
  • 您是否尝试为每个表使用TClientDataSet
  • @Victoria 首先我们打开master,然后我们打开details。之前打开详细数据集并没有什么不同。仍然是相同数量的请求。
  • 与 SqlServer + Ado 配合得很好的一件事是编写一个存储过程,它返回给定主服务器的所有详细记录。你试过吗?
  • @MartynA 详细数据集查询许多不同的表。并连接到不同的可视化编辑控件。这种方法还能管用吗?

标签: delphi dataset ado


【解决方案1】:

自从我这样做以来已经有一段时间了,所以我不再能够访问我用来对其进行基准测试的数据,但是面对类似的情况,以下的速度比标准的 Master/Details 有了巨大的提升,而且非常少努力。当然可以。

在服务器上定义一个存储过程来检索所有详细数据集的所有行,就像这样

create procedure GetDetails(@MasterID int) as
begin
  select * from Details1 where MasterID = @MasterID 
  select * from Details2 where MasterID = @MasterID 
  /* etc */
end

在客户端中,设置一个数据模块,它有一个 AdoStoredProc,它调用存储的过程和与 Detail 表一样多的 AdoDatasets。

要检索详细数据集的行,请使用如下代码

var
  Rows : Integer;
[...]
spGetDetails.Parameters.ParamByName('@MasterID').Value := MasterID;
spGetDetails.Active := True;

Details1.RecordSet := spGetDetails.RecordSet;
Details1.Active ;= True;

Details2.RecordSet := spGetDetails.NextRecordSet(Rows);
Details2.Active ;= True;

Details3.RecordSet := spGetDetails.NextRecordSet(Rows);
Details3.Active ;= True;
  //  etc, you get the idea

当然,Details1..N AdoDataSets 可以连接到标准的 db-aware 编辑控件或服务器作为一组 TClientDataSets 的提供者。

顺便说一句,这在数据模块位于 3 层设置的中间层时特别有效,因为我可以将所有详细信息行打包到压缩流中,然后 dm 将其发送到客户端。

更新 以这种方式获取 Details 表的行似乎可以很好地编辑和查看它们,我无法立即明白为什么 Details 表不支持插入和删除。每个细节 ADODatasets 都需要像往常一样为 M->D 的细节端进行配置,使用 CommandText 像 'select * from Detailx where MasterID = MasterID`。

【讨论】:

  • 令人印象深刻!关于这个解决方案的几个问题。分配详细记录集后是否可以释放 spGetDetails,而不影响详细信息?细节还能照常使用Insert、Edit、Post、Delete方法吗?
  • 嗯,当我这样做时,纯粹是为了查看,而不是编辑详细信息的数据。我不确定您为什么要释放 spGetDetails,因为那样每次 Master 滚动时您都需要重新创建它。我认为将对 Details 所做的更改写回他们的表中不会太难,但需要比通常 MD 的详细信息方面更多的代码。
  • 查看我的答案的更新。我还没有测试过插入和删除,但是由于对细节行的编辑工作正常,我不能立即明白为什么插入和删除也不起作用。
  • 就是这样,谢谢。我将使用 TADOQuery,语句由 ; 分隔。而不是存储过程,但其他方面基本相同
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-11
  • 2012-10-08
  • 1970-01-01
  • 1970-01-01
  • 2021-11-16
  • 1970-01-01
  • 2010-09-21
相关资源
最近更新 更多