使用 ADO 具有预读功能的 DBGrid

发布于 2024-12-21 20:41:15 字数 302 浏览 3 评论 0原文

我正在使用 ADO 连接到 SQL Server 2005。

我的 TADODataSet 选择 100 万条记录。使用 TDBGrid 并将 TADODataSet.CursorLocation 设置为 clUseServer 可以。但 TDBGrid 窒息了!

如何选择 100 万条记录,避免分页,并且仍然能够在网格中显示记录,而不将所有记录提取到客户端,让网格在我上下滚动时提前读取?

SQL企业管理器可以异步执行查询并选择100万条记录,没有任何问题(也是MS-ACCESS)。

I'm working with ADO connecting to SQL Server 2005.

My TADODataSet selects 1 million records. using a TDBGrid and setting the TADODataSet.CursorLocation to clUseServer works. but the TDBGrid chokes!

How can I select 1 million records, avoid paging, and still be able to display records in the grid without fetching ALL records to the client side, letting the Grid read ahead as I scroll up and down?

SQL enterprise manager can execute a query and select 1 million records asynchronously without any problems (also MS-ACCESS).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

秋千易 2024-12-28 20:41:15

TGrid 不是你的问题。您的问题是 TADODataset 正在尝试加载所有记录。如果必须运行返回如此多记录的查询,则应设置 ExecuteOptions,尝试 eoAsyncExecute 和 eoAsyncFetch。设置 CacheSize 也可能有所帮助。

TGrid is not your problem. Your problem is TADODataset is trying to load all the records. If you must run a query that returns so many records, you should set ExecuteOptions, try eoAsyncExecute and eoAsyncFetch. It may also help to set CacheSize.

少女的英雄梦 2024-12-28 20:41:15
  • 为什么需要将 1M 条记录提取到网格中?没有人能够查看如此多的记录。通常最好在将记录加载到 UI 之前减少记录数量。
  • 如果您有充分的理由在网格中显示如此多的记录,则需要一个1)在打开时不会加载整个记录集的数据集2)不缓存以前的记录,否则如果记录大小不够小,它可能会在到达记录集末尾之前就耗尽内存(尤其是在 32 位 Windows 下)。要获得超出 CursorLocation 的结果,您必须正确设置 CursorType 和 CacheSize。
  • 您可以使用 TClientDataset 来实现增量获取,将 ADO 数据集 CursorType 设置为 ForwardOnly,并将 CacheSize 设置为合适的值。由于 TClientDataset 缓存读取记录,因此您希望避免源数据集也加载所有这些记录。标准数据库网格需要双向光标,因此它无法与单向光标一起使用。有了如此多的记录,客户端数据集缓存无论如何都会耗尽内存。如果您使用的是 Delphi 版本,我建议使用 Midas Speed Fix 单元 2010 年之前。
  • 为了避免“内存不足”错误,您可能需要实现某种分页。无论如何,检查其他 CursorType 的行为是否可以帮助您。
  • Why do you need to fetch 1M records into a grid? No human being can look at so many records. Usually is far better to reduce the number of records before loading them into a UI.
  • If you have a good reason to show so many records into a grid, you'd need a dataset that 1) doesn't load the whole recordset when opened 2) doesn't cache previous record or it could run out of memory (under 32 bit Windows especially) far before reaching the end of the recordset if the record size is not small enough. To obtain such result beyond CursorLocation you have to set CursorType and CacheSize properly.
  • You can use a TClientDataset to implement incremental fetching setting the ADO dataset CursorType to ForwardOnly and CacheSize to a suitable value. Because TClientDataset caches read records, you want to avoid the source dataset to load all of them as well. A standard DB grid needs a bidirectional cursor, thereby it won't work with an unidirectional one. With so many records the client dataset cache can exhaust memory anyway. I'd suggest to use the Midas Speed Fix unit if you're using a Delphi version before 2010.
  • To avoid "out of memory" errors you may need to implement some kind of pagination. Anyway, check if the behaviour of other CursorType can help you.
一指流沙 2024-12-28 20:41:15

您可以尝试 AnyDAC 和 TADTable。其实时数据窗口模式可以解决您的问题和类似的问题。好处是:

  • 最大限度地减少内存使用,并允许处理大数据量,类似于单向数据集;
  • 与单向数据集相比,支持双向导航;
  • 始终提供新鲜数据,减少刷新数据集的需要;
  • 不延迟获取所有结果集记录,需要执行排序、记录定位、跳转到最后一条记录等。

You can try AnyDAC and TADTable. Its Live Data Window mode solves your and similar issues. The benefits are:

  • minimizes memory usage and allows to work with large data volumes, similar to an unidirectional dataset;
  • enables bi-directional navigation, in contrast to an unidirectional dataset;
  • gives always fresh data, reducing the need to refresh dataset;
  • does not delay to fetch all result set records, required to perform sorting, record location, jumping to last record, etc.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文