2011-12-15 26 views
5

Tôi đang sử dụng các thành phần ZEOS để kết nối với cơ sở dữ liệu MDB (cũ).
Tôi đang thực hiện truy vấn đọc nhiều dữ liệu để kết nối với một cơ sở dữ liệu khác.Trên truy vấn rất chậm, làm cách nào để chỉ ra phần trăm tiến trình

Có cách nào để biểu thị tiến độ dưới dạng phần trăm không?

procedure TForm13.ActionReadInMemoryExecute(Sender: TObject); 
var 
    QueryLine: string; 
    FullQuery: string; 
    Tablename: string; 
    i: integer; 
begin 
    i:= 0; 
    TableMeter.DisableControls; 
    try 
    TableMeter.First; 
    FullQuery:= ''; 
    while not TableMeter.eof do begin 
     Tablename:= TableMeter.FieldByName('tabelnaam').AsString; 
     QueryLine:= ReplaceStr(ImportQuerySjabloon, cTabelname, Tablename); 
     FullQuery:= FullQuery + QueryLine; 
     if (TableMeter.RecNo < (TableMeter.RecordCount -1)) then begin 
     FullQuery:= FullQuery + ' UNION ALL '; 
     end; 
     TableMeter.Next; 
    end; {while} 
    QueryImportMeterreadings.Close; 
    QueryImportMeterreadings.SQL.Text:= FullQuery; 
    QueryImportMeterreadings.Open; <<-- takes a long time 
    finally 
    TableMeter.EnableControls; 
    end; 
end; 

Có cách nào để chỉ ra sự tiến bộ của truy vấn, hoặc tôi chỉ có thể làm được điều này nếu tôi chia tay các truy vấn cá nhân và loại bỏ các UNION 's.
Mất khoảng 1 phút để chạy, liên quan đến 8 công đoàn.

Tôi không thấy bất kỳ sự kiện mà tôi có thể sử dụng cho mục đích này:

Hoặc nên tôi giả một OnCalcField trên một sân trong Query để làm điều này (không chắc chắn nếu điều đó thậm chí sẽ làm việc trên nguyên tắc).
Hoặc đính kèm một chuỗi? nope, cung cấp cho hoạt động không được hỗ trợ trên Access DB

+0

Như tôi đã đề cập trong nhận xét bên dưới, dựa trên câu trả lời của user1031312, bạn có thể đặt dữ liệu vào lưới chuỗi thay thế, trừ khi bạn phụ thuộc vào chức năng của DBGrid. Nếu một TStringGrid là OK, tôi có thể cho bạn một ví dụ tốt nếu cần thiết để phân chia các truy vấn và kết hợp các kết quả trong cùng một lưới ... –

+0

@ JerryDodge, tôi chỉ cần truy cập chỉ đọc, do đó, một stringgrid sẽ làm việc cho tôi. – Johan

+1

Nếu không biết tổng số bản ghi, sẽ rất khó để hiển thị thông tin 'x phần trăm đã hoàn thành' – mjn

Trả lời

3

Tôi nói chia nhỏ các truy vấn riêng lẻ và loại bỏ liên kết, đặt hẹn giờ xung quanh mỗi truy vấn, tùy thuộc vào thời gian avg thực hiện * số truy vấn còn lại bạn nên ước tính/cập nhật trường văn bản để nói x trong số các truy vấn y đã hoàn thành (thời gian còn lại: -time-)

+1

Tôi có thể tạo một thành phần Truy vấn cho mỗi truy vấn và chạy từng cái một. Vấn đề là tôi muốn hiển thị dữ liệu trong một lưới và đó là loại khó với các dữ liệu tất cả chia ra. – Johan

+0

Tôi không nghĩ rằng bạn cần một thành phần truy vấn cho mỗi, chỉ sau khi bạn đã kết thúc với một truy vấn, hãy chuyển sang câu lệnh tiếp theo trong cùng một thành phần - nhưng bạn vẫn có điểm rõ ràng bằng cách đính kèm nguồn dữ liệu để hiển thị dữ liệu ... –

+0

Nếu đúng như vậy, có thể tạo tập dữ liệu khách hàng của riêng bạn? Bạn có thể kết hợp kết quả từ nhiều truy vấn hoặc chỉ thêm dữ liệu của riêng bạn theo yêu cầu - Nhưng tôi đã thành thật chưa bao giờ làm việc với chúng. Bởi âm thanh của tình huống của bạn, nếu bạn quyết định tách từng câu lệnh như được đề cập trong câu trả lời này, thì bạn sẽ cần kết hợp dữ liệu bằng cách nào đó trong tập dữ liệu của riêng bạn, sau đó đính kèm dữ liệu đó vào nguồn dữ liệu (do đó làm việc trong lưới). –

3

Tôi sẽ chia truy vấn lớn thành các truy vấn riêng lẻ; trong mã, bạn lặp qua bộ kết quả của mỗi truy vấn và chèn các giá trị vào một clientdataset (cds) theo cách thủ công. Các CD có thể được kết nối với một dbgrid. Sau đó, bạn có thể hiển thị khi mỗi truy vấn hoàn tất - bạn cũng có thể hiển thị tiến trình sau mỗi bộ xử lý được xử lý, nhưng bạn sẽ không biết có bao nhiêu bộ dữ liệu, trừ khi bạn thực hiện truy vấn riêng trả về số lượng bộ dữ liệu. Vấn đề với việc sử dụng một cds chưa kết nối như vậy là bạn phải xác định các trường trong mã. Đây là một ví dụ về một cái gì đó tương tự mà tôi đã viết đêm qua - các truy vấn tất cả cập nhật một lĩnh vực trong CD.

const 
field1 = 'id'; 
field2 = 'customer name'; 
field3 = 'total debt'; 

procedure TTotalCustDebt.FormCreate(Sender: TObject); 
var 
strings: tstrings; 

begin 
with qTotalDebt do // this is the clientdataset 
    begin 
    fielddefs.add (field1, ftInteger, 0, false); 
    fielddefs.add (field2, ftString, 32, false); 
    fielddefs.add (field3, ftInteger, 0, false); 
    createdataset; 
    fieldbyname (field1).visible:= false; 
    open; 
    addindex ('idx0', field2, [], '', '', 0); 
    addindex ('idx1', field2, [ixDescending], '', '', 0); 
    addindex ('idx2', field3, [], '', '', 0); 
    addindex ('idx3', field3, [ixDescending], '', '', 0); 
    strings:= tstringlist.create; 
    getindexnames (strings); 
    strings.free; 
    end; 
end; 

procedure TTotalCustDebt.PopulateCDS; 
begin 
dsTotalDebt.dataset:= nil; 
with qTotalDebt do 
    begin 
    emptydataset; 
    indexfieldnames:= field1; // initially sort by customer.id 
    end; 

with qDBills do 
    begin 
    params[0].asdate:= dt; 
    open; 
    while not eof do 
    begin 
    qTotalDebt.append; 
    qTotalDebt.fieldbyname (field1).asinteger:= qDBillsID.asinteger; 
    qTotalDebt.fieldbyname (field2).asstring:= qDBillsName.asstring; 
    qTotalDebt.fieldbyname (field3).asinteger:= qDBillsTot.asinteger; 
    qTotalDebt.post; 
    next 
    end; 
    close 
    end; 

    // show progress indicator 

    with qDReceipts do 
    begin 
    params[0].asdate:= dt; 
    open; 
    while not eof do 
    begin 
     if qTotalDebt.findkey ([qDReceiptsID.asinteger]) then 
     begin // customer already exists 
     qTotalDebt.edit; 
     qTotalDebt.fieldbyname (field3).asinteger:= - qDReceiptsTot.asinteger 
            + qTotalDebt.fieldbyname (field3).asinteger; 
     end 
    else 
     begin // add new record 
     qTotalDebt.append; 
     qTotalDebt.fieldbyname (field1).asinteger:= qDReceiptsID.asinteger; 
     qTotalDebt.fieldbyname (field2).asstring:= qDReceiptsName.asstring; 
     qTotalDebt.fieldbyname (field3).asinteger:= - qDReceiptsTot.asinteger; 
     end; 
    qTotalDebt.post; 
    next 
    end; 
    close 
    end; 

// show progress indicator 
// more queries 
// at end, attach the clientdataset to the TDataSource 
dsTotalDebt.dataset:= qTotalDebt; 
end; 
Các vấn đề liên quan