2010-01-21 6 views
0

У меня есть много методов в устаревшем коде, которые используют TIBQuery (Interbase) с однонаправленным свойством = False. Проблема в том, что пользователи иногда получают исключение из памяти. Я подозреваю, что это можно исправить, установив для этого свойства значение True, так как нет необходимости кэшировать записи.TIBQuery.Unidirectional = True. Как я могу переписать код?

Конечно, я не хочу нарушать старый код, но я также хочу исправить проблему.

Здесь приведен пример кода (не завершена из-за размера):

procedure TAnalyzeForm.CostByInvoice; 
begin 
    try 
    qryReport.Close; 
    qryReport.Open; 
    qryReport.Last; 
    qryReport.First; 
    if qryReport.RecordCount > 0 then 
    begin 
     for i := 0 to qryReport.RecordCount - 1 do 
     begin 
     vInvoiceNo := Format('%-8s', [qryReport.FieldValues['InvoiceNo']]); 
     vDeptId := Format('%8s', [qryReport.FieldValues['DepartmentId']]); 
     vOrgName := Format('%-22s', [qryReport.FieldValues['OrgName']]); 
     vInvDate := qryReport.FieldValues['InvoiceDate']; 
     vInvNetCur := qryReport.FieldValues['InvNetCur']; 
     vInvVatCur := qryReport.FieldValues['InvVatCur']; 
     vInvTotCur := qryReport.FieldValues['InvTotCur']; 
     vInvCur := qryReport.FieldValues['UnitId']; 
     vTotNet := vTotNet + qryReport.FieldValues['InvNetValue']; 
     vTotVat := vTotVat + qryReport.FieldValues['InvVatValue']; 
     vTotTot := vTotTot + (qryReport.FieldValues['InvNetValue'] + qryReport.FieldValues['InvVatValue']); 
     grdCost.Cells[1, i+1] := vInvoiceNo; 
     grdCost.Cells[2, i+1] := vDeptId + ' ' + vOrgName; 
     grdCost.Cells[3, i+1] := FormatDateTime('dd.mm.yyyy', vInvDate); 
     grdCost.Cells[4, i+1] := Format('%12.2f', [vInvNetCur]); 
     grdCost.Cells[5, i+1] := Format('%12.2f', [vInvVatCur]); 
     grdCost.Cells[6, i+1] := Format('%12.2f', [vInvTotCur]); 
     grdCost.Cells[7, i+1] := 'EUR'; 
     grdCost.RowCount := i+1 + 1; 
     qryReport.next; 
     end; 
     txtNetCost.Caption := Format('%12.2f', [vTotNet]); 
     txtVatCost.Caption := Format('%12.2f', [vTotVat]); 
     txtTotCost.Caption := Format('%12.2f', [vTotTot]); 
     SummaryInfo(stSummaryInfoCost, 'Number of costinvoices: ' + IntToStr(qryReport.RecordCount), time, true); 
    end 
    else 
     MessageDlg('nothing found!', mtInformation, [mbOk], 0); 
    finally 
    qryReport.Close; 
    end; 
end; 

Важной переменной является qryReport, что является TIBQuery. Я хочу переписать его так, чтобы я мог установить TIBQuery.Unidirectional = True. qryReport повторно используется во многих местах с различным SQL, поэтому я думаю, что это причина для последовательности Close, Open в начале.

ответ

1

Если один и тот же экземпляр используется со многими SQL-запросами, и вы несете основную озабоченность - это не разорвать приложение, при необходимости вы можете сохранить значение свойства Unidirectional, установить его в True, использовать объект и восстановить его на своем первоначальное значение в конце.

Что-то вроде:

var 
    OldUnnidirectionalValue: Boolean; 
begin 
    OldUnnidirectionalValue := qryReport.Unnidirectional; 
    qryReport.Unnidirectional := True; 
    try 
    qryReport.SQL.Text := 'select what you want'; 
    qryReport.Open; 
    try 
     while not qryReport.eof do 
     begin 
     UseTheRecord; 
     qryReport.Next; 
     end; 
    finally 
     qryReport.Close; 
    end; 
    finally 
    qryReport.Unnidirectional := OldUnnidirectionalValue; 
    end; 
end; 

Избегайте Закрыть Открыть последовательность, вы должны использовать попытаться /, наконец, блоки всегда закрывать запрос после использования.

С уважением;)

+0

Выглядит разумно, спасибо за пример. –

7

После того, как вы установили однонаправленное значение в True, вы можете звонить только сначала и далее. Этот код всегда был плохим. Вы никогда не должны использовать RecordCount для перебора записей. Используйте Next и EOF. Таким образом, вам не нужно вызывать Last, чтобы заставить базу данных загрузить весь набор результатов, чтобы узнать, сколько записей есть.

+0

Благодарим за ответ! Я попробую это. –

+0

+1 Согласен с Luigi –

Смежные вопросы