Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Konzeptfrage Ergebnismenge einer Funktion (https://www.delphipraxis.net/107721-konzeptfrage-ergebnismenge-einer-funktion.html)

WIng2005 1. Feb 2008 08:22


Konzeptfrage Ergebnismenge einer Funktion
 
Hallo,

ich habe folgendes vor:

eine Prozedur ruft eine Funktion auf, in welcher durch div. DB-Abfragen eine Ergebnismenge folgender Struktur:

Baugruppe Einzelteil Wert 1 ... Wert n
-------------------------------------------------
1-----------A------------23-----------34
1-----------B
1-----------C
1-----------A------------usw.
1-----------C
1-----------F

zusammen gebastelt wird. Diese Menge wird von der Prozedur verarbeitet und abgelegt.
Wie würdet ihr die Übergabe der Ergebnismenge (kann sehr groß werden) lösen(Array,Stringliste...)?
Die Daten sollten sortiert und (am Bsp. A) zusammengefaßt werden können. Mein Problem mit nem Array ist, dass ich
die größe der Ergebnismenge nich in der Prozedure kenne und somit das Array nicht definieren kann.

MFG
Steffen

Nikolas 1. Feb 2008 08:25

Re: Konzeptfrage Ergebnismenge einer Funktion
 
Bau dir doch ein Record, in das du die ermittelten Werte schreiben kannst.
Dann mache dir ein Array auf genau diesem Typ und arbeite damit. Dass du die Arraygröße nicht kennst, ist nicht so wichtig, da genau für diesen Fall die dynamischen Arrays eingebaut wurden.

mashutu 1. Feb 2008 08:45

TQuery zurueckgeben
 
du schreibst sehr wenig, ueber das, was da zusammengestellt wird, aber u.U. kann es angemessen sein eine Query zurueckzugeben.

So als grundsaetzliches Beispiel.

Delphi-Quellcode:
function getMyData(...hier die Bedingungen uebergeben..):TQuery;
var
  ...
begin
   result:=TQuery.create(NIL);
   result.sql.add(...) //SQL zusammenbasteln

   result.open;
end;
Du musst dann halt nach der Bearbeitung/Weiterverarbeitung darauf achten die Query wieder freizugeben.
Aber damit kannst Du auch die Sortierung steuern und die anzahl der Ergebnismenge laesst sich auch ermitteln.

WIng2005 1. Feb 2008 09:00

Re: Konzeptfrage Ergebnismenge einer Funktion
 
Die Ergebnismenge ist eine Auflistung aller Einzelteile eines Gerätes. Da dieses jedoch weitere
Unterbaugruppen enthalten kann (bis 5 Strukturstufen) sind mehrere Einzelabfragen an die gleiche DB-Tabelle
nötig. Bin fast dran, die Ergebnismenge in eine Datei zu schreiben und dann wieder auszulesen.
@Nikolas: muß ich nicht bei dynamischen Array die Größe vorab definieren und kann sie dann
verändern? Da die Funktion ja aber nur die Menge selbst zurückgibt, stelle ich mir die Zuweisung der Ergebnismenge in der Prozedur schwierig vor.

MFG
Steffen

DeddyH 1. Feb 2008 09:03

Re: Konzeptfrage Ergebnismenge einer Funktion
 
Zitat:

Zitat von WIng2005
muß ich nicht bei dynamischen Array die Größe vorab definieren und kann sie dann
verändern?

Jepp, siehe dazu SetLength.

angos 1. Feb 2008 09:09

Re: TQuery zurueckgeben
 
Zitat:

Zitat von mashutu
So als grundsaetzliches Beispiel.

Delphi-Quellcode:
function getMyData(...hier die Bedingungen uebergeben..):TQuery;
var
  ...
begin
   result:=TQuery.create(NIL);
   result.sql.add(...) //SQL zusammenbasteln

   result.open;
end;

So sollte man das nicht machen. Wie soll die TQuery wieder freigegeben werden?

Besser ist es, die TQuery als var-Parameter zu übergeben.

Delphi-Quellcode:
function getMyData(..., aQuery: TQuery): Boolean;
var
  ...
begin
  Result := True;
  Result.sql.add(...) //SQL zusammenbasteln
  try
    result.open;
  except;
    Result := False;
  end;

end;


procedure machwas;
var
  aQuery: TQuery;
begin
  aQuery := TQuery.Create(NIL);
  try
    if getMyData(..., aQuery) = True then
    begin
      // Machwas
    end;
  finally
    aQuery.Close;
    aQuery.Free;
  end;
end;

mashutu 1. Feb 2008 09:46

Re: TQuery zurueckgeben
 
Zitat:

Zitat von angos
Zitat:

Zitat von mashutu
So als grundsaetzliches Beispiel.

Delphi-Quellcode:
function getMyData(...hier die Bedingungen uebergeben..):TQuery;
var
  ...
begin
   result:=TQuery.create(NIL);
   result.sql.add(...) //SQL zusammenbasteln

   result.open;
end;

So sollte man das nicht machen. Wie soll die TQuery wieder freigegeben werden?

Na das Aufrufende Modul.

Das machst Du in Deinem Beispiel doch auch und ich habe auch darauf hingewiesen.

DeddyH 1. Feb 2008 09:49

Re: Konzeptfrage Ergebnismenge einer Funktion
 
Hier gab es mal einen längeren Thread dazu: Link

WIng2005 1. Feb 2008 10:42

Re: Konzeptfrage Ergebnismenge einer Funktion
 
Habe leider noch keine Erfahrungen mit TQuery. Bin auch nicht ganz sicher,
ob hier schon die Tatsächliche Ergebnismenge, oder nur die fertige Abfrage-
syntax erstellt wird. Die Abfragen sind zu komplex, als dass sie mit einer Abfrage
gelöst werden kann.

MFG
Steffen

angos 1. Feb 2008 11:07

Re: TQuery zurueckgeben
 
Wenn du das nicht mit einer SQL-Abfrage realisieren kannst, wird dir die Query wohl nicht weiterhelfen, aber normalerweise bekommt man durch ne SQL-Abfrage schon gut alle infos die man braucht (die Abfrgae kann natürlich lang und mit diversen Unterabfragen ausgestattet sein ;) )


OT:

Zitat:

Zitat von mashutu
Na das Aufrufende Modul.

Das machst Du in Deinem Beispiel doch auch und ich habe auch darauf hingewiesen.

hmm verstehe ich nicht ganz. Der Unterschied ist: Ich erzeuge das Objekt in der "Hauptfunktion", Übergebe dass dann an die Funktion zu FÜllen und arbeite damit dann wieder in der Hauptroutine, wo ich es anschließend freigebe.

Du erzeugst in der Unterfunktion das Objekt. würde das dann so funktionieren, oder wie meinst du das?:
Delphi-Quellcode:
function myData: TQuery;
begin
...
end;

procdure Hauptroutine;
begin
  with myData do
  begin
    try
      // Mach was
    finally
      Free; // Wird jetzt hierdurch das in der funktion myData erzeugte Obejkt wieder freigeben??
    end;
  end;
end;
Gruß
Ansgar

mashutu 1. Feb 2008 11:24

OT: Re: TQuery zurueckgeben
 
So war das gemeint:

[Edit: ganz sauber]
Delphi-Quellcode:
function myData: TQuery;
begin
...try
     result:=TQuery.create(NIL);
   except
     if assigned(result) then
        FreeAndNil(result);
   end
end;

procedure Hauptroutine;
var
  qry : TQuery;
begin
  qry:=myData;
  if qry <> NIL then
  with qry do
  begin
    try
      // Mach was
    finally
      Free;
    end;
  end;
end;
Die query wird in der Hauptroutine als Variable deklariert, das Erstellen mit schnickschnack passiert woanders und die Query wird da freigegeben wo sie auch deklariert ist. Das gibt keine Probleme.

WIng2005 1. Feb 2008 11:32

Re: Konzeptfrage Ergebnismenge einer Funktion
 
kann ich nem Query mehrere Selects vergeben, wobei das jeweils nachfolgende
Select die Ergebnismenge des Vorgängers nutzt?

Quasi so:
Select x1,x2 INTO temp_1 From Tabelle_1
Select x1,x2 From Temp_1 Where x1= Bed1


MFG
Steffen

angos 1. Feb 2008 12:10

Re: Konzeptfrage Ergebnismenge einer Funktion
 
Zitat:

Zitat von WIng2005
kann ich nem Query mehrere Selects vergeben, wobei das jeweils nachfolgende
Select die Ergebnismenge des Vorgängers nutzt?

Quasi so:
Select x1,x2 INTO temp_1 From Tabelle_1
Select x1,x2 From Temp_1 Where x1= Bed1


MFG
Steffen

ja das geht. Hier ein kleines beispiel

SQL-Code:

Select x1, x2 from
(Select x1, x2 from Tabelle_1 where x1 = Bed1)

WIng2005 2. Feb 2008 07:20

Re: Konzeptfrage Ergebnismenge einer Funktion
 
Vielen Dank, werde ich Montag gleich mal ausprobieren.....
Wie ich nun die Übergabemenge löse, ist mir nur irgendwie immernoch nicht ganz klar.
Bisher bin ich, wie gesagt, ein wenig auf ner Datei (ini) hängengeblieben, finde dies aber ein wenig unsauber....


MFG
Steffen

grenzgaenger 2. Feb 2008 07:26

Re: Konzeptfrage Ergebnismenge einer Funktion
 
aber sag mal, weshalb willste denn so viele datensätze zurückliefern?

das einzige wo das sinn machen könnte, wäre beim ausdruck... und da wäre es sinnvoll die daten vom server abzuholen und gleich zu drucken...

grüsse und noch einen schönen samstag
GG

alzaimar 2. Feb 2008 09:39

Re: OT: Re: TQuery zurueckgeben
 
Zitat:

Zitat von mashutu
So war das gemeint:

[Edit: ganz sauber]

Was Du da machst ist schon sehr merkwürdig. In der Funktion erzeugst Du eine Query und zerstörst sie dann. Ergo liefert 'MyData' immer nil.
So würde ich das machen:
Delphi-Quellcode:
Procedure Hauptroutine;
Var
  qMyQuery : TQuery;        // riecht nach BDE, lieber nicht verwenden

Begin
  qMyQuery := TQuery.Create (nil);
  Try                       // --- dieses Try kapselt die Instantiierung der TQuery-Komponente
    // qMyQuery mit der Datenbank verbinden
    qMyQuery.SQL.Text := 'Select * from View_VerdammtKomplexeAbfrage';
    qMyQuery.Open;
    Try                     // --- dieses Try kapselt das Öffnen der Query
      qMyQuery.First;       // Nicht nötig, aber illustriert, das man vom ANFANG anfangen will.
      While Not qMyQuery.Eof Do Begin
        DoSomething (qMyQuery);
        qMyQuery.Next;
      End;
    Finally
      qMyQuery.Close;
    End;
  Finally
    qMyQuery.Nil;           // FreeAndNil ist überflüssig, da qMyQuery lokal ist und nicht weiter verwendet wird.
  End
End;
Wieso schreibe ich die Instantiierung VOR das Try? Weil laut Guidelines ein Konstruktor keine logischen Prüfungen vornimmt und insofern (außer bei Speichermangel oder anderen fatalen Fehlern) nicht abschmiert. Und fatale Fehler muss man nicht abfangen, weil das eben :zwinker: fatal sein kann. Einen Speichermangel abzufangen, um eine Messagebox anzuzeigen, führt nämlich zu -jupp- einer Exception wegen Speichermangel...

WIng2005 3. Feb 2008 09:35

Re: Konzeptfrage Ergebnismenge einer Funktion
 
Prinzipiell soll die Funktion für verschiedene Einsatzzwecke flexibel nutzbar sein.
Zum eine für die Darstellung in Grids, zum anderen für Berechnungen.

MFG
Steffen

alzaimar 3. Feb 2008 10:31

Re: Konzeptfrage Ergebnismenge einer Funktion
 
Ich würde die Daten in eine Objektstruktur laden, dort mit ihnen arbeiten, um sie dann wieder abzuspeichern.

Da dies eine Standardanforderung ist, gibt es natürlich schon Lösung für das Laden und Speichern der Daten in ein Objekt. Du kannst Dir mal die InstantObjects von Sourceforge runterladen. Das ist eine sehr gelungene Umsetzung. Du definierst nur deine Objekte und das Laden/Speichern/Anzeigen in Grids/Bearbeiten in Feldern etc. bzw. die Vorbereitung und Bereitstellung geschieht vollautomatisch. So kannst du dich auf die Modellierung deiner Objekte kümmern.

mashutu 4. Feb 2008 09:31

Re: OT: Re: TQuery zurueckgeben
 
Zitat:

Zitat von alzaimar
Was Du da machst ist schon sehr merkwürdig. In der Funktion erzeugst Du eine Query und zerstörst sie dann. Ergo liefert 'MyData' immer nil.

Quatsch, im Except Fall liefert die Funktion NIL, ansonsten ein gueltiges Objekt - in dem Fall eine TQuery.
Okay, das mir in dem Beispiel das create vor das try gerutscht ist, mag unschoen sein, aber es ist ja nur ein Beispiel.

WIng2005 6. Feb 2008 05:47

Re: Konzeptfrage Ergebnismenge einer Funktion
 
So..... habe es nun in einer csv abgelegt. So kann ich es an beliebiger Stelle neu laden.

Vielen Dank für eure Anregungen....

MFG
Steffen

WIng2005 7. Feb 2008 08:26

Re: Konzeptfrage Ergebnismenge einer Funktion
 
Nur mal so als Nachtrag: kann der Rückgabewert einer Funktion ein mehrdimensionales
Array sein? Z.Bsp. So:

funktion test(test1:string):array of array of string;

??? Diese Version selbst, will jedoch bei mir nicht funktionieren.

MFG
Steffen

mashutu 7. Feb 2008 08:38

Re: Konzeptfrage Ergebnismenge einer Funktion
 
Zitat:

Zitat von WIng2005
Nur mal so als Nachtrag: kann der Rückgabewert einer Funktion ein mehrdimensionales
Array sein? Z.Bsp. So:

funktion test(test1:string):array of array of string;

??? Diese Version selbst, will jedoch bei mir nicht funktionieren.

MFG
Steffen

Dazu muesstest du das asl Typ definieren.

WIng2005 7. Feb 2008 08:43

Re: Konzeptfrage Ergebnismenge einer Funktion
 
Ja, hatte ich grad hier in nem anderen Beitrag gelesen (ich sollte erst suchen......)
"Wurschtel" mich grad mal durch.

Trotzdem Danke
MFG
Steffen


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:36 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz