2008-12-05 30 views
6

Tôi không phải là một lập trình viên Delphi, nhưng tôi có một ứng dụng Delphi 7 cũ mà tôi cần sửa chữa và nó đang sử dụng ADO.Làm thế nào để ngăn chặn Delphi ADO tải toàn bộ bảng vào bộ nhớ?

Bảng cơ sở dữ liệu (MS Accesss) chứa +100.000 hàng và khi tôi đặt ADOTable.Active = true, nó bắt đầu tải toàn bộ bảng vào RAM và mất rất nhiều bộ nhớ và thời gian.

Làm cách nào để ngăn ADO tải toàn bộ bảng? Tôi đã cố gắng để thiết lập MaxRecords nhưng nó không giúp đỡ.

Về cơ bản tất cả chúng ta làm là att chương trình khởi động:

// Connect to database 
DataModule.MyADOConnection.Connected:=true; 

DataModule.MeasurementsADOTable.MaxRecords:=1; 

// Open datatables 
DataModule.MeasurementsADOTable.Active:=true;     

Sau khi thiết lập kích hoạt = true nó bắt đầu để tải toàn bộ đo vào RAM và phải mất thời gian!

Chúng tôi đang sử dụng nhà cung cấp MSDASQL.1. Có lẽ nó không hỗ trợ tài sản MaxRecords?

Làm cách nào để thêm một số truy vấn hạn chế vào đối tượng dữ liệu này để chỉ "tải TOP 1 * từ các phép đo"?

Trả lời

10

Bạn có thể sử dụng TADOQuery để giới hạn tập hợp kết quả bằng truy vấn sql. Hoặc bạn có thể sử dụng TADOTable và đặt CursorLocation thành con trỏ phía Máy chủ để ngăn máy khách tải toàn bộ kết quả trong bộ nhớ.

0
  1. On datamodule của bạn, nơi "MeasurementsADOTable" hiện cư trú, thả một TADOQuery và đặt tên là "MeasurementsADOQuery"
  2. Thiết lập thuộc tính kết nối của MeasurementsADOQuery để MyADOConnection (giả sử đây là trường hợp dựa trên các đoạn mã nhỏ được cung cấp.)
  3. Tôi cũng giả sử rằng bạn đang hiển thị lưới hoặc bằng cách sử dụng Nguồn dữ liệu - thay đổi thuộc tính "Số liệu" của thành phần DataSource từ MeasurementsADOTable thành MeasurementsADOQuery
  4. Chỉnh sửa truy vấn thực tế được thực hiện bằng cách đặt thuộc tính SQL của MeasurementsADOQuery . (Trong thời gian chạy trước khi mở: Measurements.SQL.Text: = 'chọn top 10 * từ các phép đo thứ tự bởi bất cứ điều gì')
  5. Analyze/thay đổi tất cả tài liệu tham khảo trong mã từ MeasurementsADOTable để MeasurementsADOQuery
5

Bạn có thể sử dụng mà adoTable với một con trỏ Server OpenForwardOnly và một TCLientDataset với PacketRecords được đặt thành giá trị nonzero. Đã làm việc tuyệt vời khi tôi phải viết một ứng dụng để bơm dữ liệu từ MSSQL đến Oracle theo cách tùy chỉnh với các bảng có hàng triệu bản ghi.

EDIT -> Nó sẽ là một cái gì đó trên dòng này:

procedure ConfigCDSFromAdoQuery(p_ADOQ: TADOQuery; p_CDS: TClientDataset; p_Prov: TDatasetProvider); 
begin 
    If p_ADOQ.Active then p_ADOQ.Close; 
    p_ADOQ.CursorLocation := clServer; 
    p_ADOQ.CursorType := ctOpenForwardOnly; 
    p_Prov.Dataset := p_ADOQ; 
    p_CDS.SetProvider(p_Prov); 
    p_CDS.PacketRecords := 100; 
    p_CDS.Open; 
end ; 

Tôi đã làm điều này tất cả bởi mã, nhưng hầu hết các bạn có thể làm trong thời gian thiết kế.

+0

làm thế nào để kết nối các TClientDataSet với MSAccess của tôi? Bạn có một số mã mẫu bạn có thể chia sẻ không? – Vlad

+1

@Vlad: Quá trình này luôn giống nhau: kết nối TClientDataset (CDS) với một TDatasetProvider (DSP), sau đó điểm thuộc tính DSP.DataSet cho ADOQuery bạn đang mang dữ liệu. Trong phần Delphi trên About.com bạn có thể tìm thấy hàng ngàn ví dụ và trong docwiki embarcadero quá. –

+0

Cảm ơn, tôi sẽ cố gắng thực hiện một dự án mẫu, nhưng vẫn là một bản demo với "Server (vị trí con trỏ?) Con trỏ OpenForwardOnly và một TCLientDataset với PacketRecords được đặt thành giá trị khác" sẽ là tuyệt vời! ;) – Vlad

-1

Tôi đã tìm thấy ADO + Access w/Delphi là chậm chạp, cho rất nhiều thứ (bảng lớn đọc như bạn đang mô tả, nhưng cũng chèn là tốt, vv). Câu trả lời của tôi đã trở thành "Thoát khỏi sử dụng ADO và truy cập hoàn toàn."

Không bao giờ hiểu tại sao nó hoạt động kém, đặc biệt là khi các công nghệ trước đó dường như không.

1

Bài viết này là BDE cụ thể, nhưng áp dụng cho ADO hoặc hầu hết các thư viện truy cập dữ liệu khách hàng.

http://dn.codegear.com/article/28160

tôi sẽ khuyên bạn sử dụng TADODataSet (nó "gần gũi" với lớp ADO hơn TADOQuery) và chỉ chọn các dữ liệu khách hàng cần bằng cách cung cấp một hình thức tìm kiếm tuỳ chỉnh (phạm vi ngày, danh sách các mục cụ thể, vv)

Chúc may mắn

0

Dont làm cho adotable hoạt động khi khởi động và biến nó thành sự thật sau là một cách nhưng vẫn không thực sự sẽ giúp đỡ .... sử dụng một adodataset và cư mà đúng hơn là cần thiết trong thời gian chạy với kết nối của bạn bản văn. Chỉ dữ liệu có liên quan mới được truy xuất để làm cho dữ liệu nhanh hơn nhiều.

0

sử dụng adoquery Nếu bạn không cần bất kỳ liên tiếp và chỉ muốn chèn lệnh sử dụng hàng sql mới như này 'select * from myTable nơi id = -1' Từ Id là autonumber không có hàng sẽ trở lại. hoặc 'chọn * từ myTable trong đó 1 = -1' Nhưng tôi nghĩ rằng đó không phải là cách tốt để Insering dữ liệu. Sử dụng adocommand chắc chắn tốt hơn nhiều.

nếu bạn muốn X hàng 'chọn top X * từ myTable'

+0

chắc chắn với ngăn chặn tải toàn bộ bảng trong bộ nhớ !!! sử dụng adoquery thay vì adotable, whit a stat condition false

Các vấn đề liên quan