Hallo zusammen,
ich arbeite an einer
SQL-Anwendung und will Euch mal fragen, ob das überhaupt die richtige Herangehensweise ist...
Ich nutze FB2 embeded mit einigen Tabellen und verschiedenen
DB-Komponenten. Hier z.B. auch eine eigene DBPanel, die
DB-Inhalte formatiert anzeigt und u.a. vom Nutzer per Drag&Drop verschoben werden kann.
Der Nutzer soll letztlich nicht merken, dass da eine Datenbank im Hintergrund steckt. Er soll sich also nicht mit Tabellen, DataSet-Status etc. herumschlagen müssen...
Es gibt eine Edit-Komponente, mit der der Nutzer Feldinhalte ändern kann, die bei jedem Tastendruck sofort in der Datenbank aktualisiert werden und überall "gleichzeitig" aktualisiert angezeigt werden.
Das ist also ähnlich den Eigenschaften im Objektinspektor (Weiss jemand eigentlich wie das in der
IDE realisiert ist, mit CDS?).
Dann gibt es in dem DataModule einige Funktionen, die Berechnungen und Änderungen in der Datenbank vornehmen. Anschließend werden die betroffenen Datenmengen geschlossen, wieder geöffnet und an die alte Stelle positioniert:
Delphi-Quellcode:
procedure TDataModuleSatzUndSieg.DauerDisziplingruppenBerechnen(DBSqlWhere:TDBSqlWhere);
var IBSQL1,IBSQL2:TIBSQL;
Disziplingruppe,C,SDG,
SDI,BDG,BDI:Integer;
begin
IBSQL1:=TIBSQL.Create(
nil);
IBSQL1.DataBase:=IBDatabaseSatzUndSieg;
IBSQL2:=TIBSQL.Create(
nil);
IBSQL2.DataBase:=IBDatabaseSatzUndSieg;
with IBSQL1
do begin
Close;
SQL.Clear;
SQL.Add('
select * from T_Disziplingruppen');
SQL.Add('
order by Id');
ExecQuery;
while (
not Eof)
do begin
Disziplingruppe:=FieldByName('
Id').AsInteger;
with IBSQL2
do begin
Close;
SQL.Clear;
SQL.Add('
select Count(*) as C from T_Disziplinen');
SQL.Add('
where (Disziplingruppe=:Disziplingruppe)');
ParamByName('
Disziplingruppe').AsInteger:=Disziplingruppe;
ExecQuery;
C:=FieldByName('
C').AsInteger;
Close;
end;
with IBSQL2
do begin
Close;
SQL.Clear;
SQL.Add('
select Sum(DauerGeplant) as BDG, Sum(DauerIst) as BDI from T_Disziplinen');
SQL.Add('
where (Disziplingruppe=:Disziplingruppe)');
ParamByName('
Disziplingruppe').AsInteger:=Disziplingruppe;
ExecQuery;
BDG:=FieldByName('
BDG').AsInteger;
BDI:=FieldByName('
BDI').AsInteger;
Close;
end;
...
Next;
end;
end;
IBSQL1.Free;
IBSQL2.Free;
RefreshDataSet(IBTableDisziplingruppen);
end;
procedure RefreshDataSet(DataSet:TDataSet;IdField:String='
';IdValue:String='
');
var TmpBookmark:TBookmark;
begin
if (DataSet<>DataSetBlocked)
then begin
with DataSet
do begin
TmpBookmark:=nil;
try
TmpBookmark:=GetBookmark;
DisableControls;
Close;
Open;
...
if (
not IsEmpty)
then begin
GotoBookmark(TmpBookmark);
end;
finally
EnableControls;
FreeBookmark(TmpBookmark);
...
end;
end;
if ((IdField<>'
')
and (IdValue<>'
'))
then begin
LocateDataSet(DataSet,IdField,IdValue);
end;
end;
end;
Hier liegt es letztlich bei mir, wann ich die DataSets aktualisiere und damit die erneute Anzeige der Datenbankinhalte veranlasse.
Das temporäre Erzeugen und Verschachteln von zwei IBSQL funktioniert, aber ...
... macht man das so, oder ist der Ansatz eher suboptimal?
(Abgesehen mal vom Einsatz von SP, die ich lieber erst mal außen vor lasse.)
stahli