Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi datensätze vergleichen (https://www.delphipraxis.net/25284-datensaetze-vergleichen.html)

Butterflyz 4. Jul 2004 00:08


datensätze vergleichen
 
hallo,
folgendes problem: sobald der einfügen-button eines DBNavigators gedrückt wird, sollen 2 tabellen abgeglichen und die werte, die NICHT gleich sind, in eine combobox gefüllt werden, in diesem fall das datum. hier die prozedur:

Delphi-Quellcode:
procedure TForm5.ADOTable1AfterInsert(DataSet: TDataSet);
var i,n : integer;
begin
  form5.qryDatum.Close;
  form5.qryMannschaften.Close;
  form5.qryMannschaften.SQL.Clear;
  form5.qryMannschaften.SQL.Text
  := 'SELECT TTermin.datum, TTermin.mannschaft_1, TTermin.mannschaft_2 FROM TTermin, TSpielergebnisse WHERE NOT (TTermin.datum = TSpielergebnisse.Datum)';
  form5.qryMannschaften.Open;
  if form5.qryMannschaften.RecordCount = 0
  then
  begin
    showmessage('Es gibt keine neuen Termine!');
    exit;
  end
  else
  begin
    n := form5.qryMannschaften.RecordCount;
    i := 0;
    form5.Datum.Clear;
    repeat
    begin
      form5.Datum.Items.Add(DateToStr(form5.qryMannschaften.FieldByName('datum').AsDateTime));
      inc(i);
      form5.qryMannschaften.Next;
    end;
    until i = n;
    form5.Datum.ItemIndex := 0;
    form5.DBEdit1.Text := form5.Datum.Text;
    form5.Label11.Caption := form5.qryMannschaften.FieldByName('mannschaft_1').AsString;
    form5.Label12.Caption := form5.qryMannschaften.FieldByName('mannschaft_2').AsString;
  end;
end;
aber irgendwie will er nicht so ganz... das problem ist: es passiert nichts. in der combobox stehen danach immer noch die gleichen einträge, und wenn alle datensätze gleich sind, der recordcount also 0 ist, wird es einfach ignoriert.... ich schätze da stimmt was nicht mit dem SQL-Statement... aber ich weiß einfach nicht mehr weiter...

MrSpock 4. Jul 2004 10:08

Re: datensätze vergleichen
 
Hallo Butterflyz,

das scheint an der Where-Klausel zu liegen:

SQL-Code:
WHERE NOT (TTermin.datum = TSpielergebnisse.Datum)
Was genau willst du damit erreichen? Gibt es in TTermin mehr als ein Datum? Falls ja, gibt es immer ein Datum in TTermin, das nicht dem Datum in TSpielergebnisse entspricht. Deshalb müsstest du immer alle Daten aus TSpielergebnisse erhalten.

MarkusB 4. Jul 2004 10:52

Re: datensätze vergleichen
 
Hi Butterflyz!

Ich vermute, dass du die TSpielergebnisse aktualisieren willst. Deswegen brauchst du die Sätze aus der TTermin die nicht in TSpielerergebnisse vorkommen. Versuche mal mit sub-select:

Delphi-Quellcode:
...
with form5.qryMannschaften do
begin
  close;
  sql.clear;
  sql.add := 'select datum, mannschaft_1, mannschaft_2';
  sql.add := '  from TTermin';            
  sql.add := ' where datum not in (select datum';
  sql.add := '                     from TSpielergebnisse)';                                                  
  Open;
end;
...
Viele Grüße
Markus
:gruebel:

Butterflyz 4. Jul 2004 11:35

Re: datensätze vergleichen
 
juhuu, vielen dank, es hat geklappt! :-D
aber: wenn es keine verschiedene datensätze gibt, dann wird das datum 31.12.1899 ausgewählt, obwohl es garnicht in TTermin steht. wie könnte man das umgehen?

MarkusB 4. Jul 2004 12:55

Re: datensätze vergleichen
 
Kannst du das ein bisschen näher erklären:
Zitat:

aber: wenn es keine verschiedene datensätze gibt, dann wird das datum 31.12.1899 ausgewählt, obwohl es garnicht in TTermin steht.
Ausgewählt? Wo? In ComboBox "Datum"?
Wenn ja, dann versuch das:
Delphi-Quellcode:
...
form5.Datum.Clear;          // <- ComboBox Datum direkt vor "if-Abfrage" putzen

if form5.qryMannschaften.RecordCount = 0
then
begin
  showmessage('Es gibt keine neuen Termine!');
  exit;
end
else
begin
  n := form5.qryMannschaften.RecordCount;
  i := 0;
  form5.Datum.Clear;        // <- IMHO zu spät. Wird nicht gemacht, falls RecordCount = 0
  repeat
  begin
    form5.Datum.Items.Add(DateToStr(form5.qryMannschaften.FieldByName('datum').AsDateTime));
...
Viele Grüße
Markus
:gruebel:

Butterflyz 4. Jul 2004 14:15

Re: datensätze vergleichen
 
oh mein gott jetzt habe ich komplett die übersicht verloren! :oops:
also ich versuche es mal zu beschreiben:

in einer tabelle sollen die ergebnisse eines fußballspeiels eingetragen werden, also tore, punkte usw.
bestimmte daten, nämlich das datum und die beiden mannschaften werden aus einer tabelle abgerufen, in der die spieletermine stehen. man soll also nur die ergebnisse dieser spiele bearbeiten können, die in der termin-tabelle stehen.
wenn man ein neues spielergebnis eintragen möchte, wird erst geguckt, ob es überhaupt einen neuen termin gibt.
wenn ja, sollen die neuen daten (mehrzahl von datum? :)), sofern es mehrere sind, in eine combobox gefüllt werden und die mannschaften werden gleichzeitig in ein label und ein DBEdit feld geschrieben und zur tabelle übertragen.
dann soll das neue datum, was in die ergebnis-tabelle aufgenommen wurde, zu den items in einer anderen combobox hinzugefügt werden (sofern es nicht schon drinsteht), so dass man die datensätze direkt per auswahl durch die combobox ansteuern kann (darin stehen nur die daten (mehrzahl von datum)).
das wärs denke ich...

was ich gemacht habe:
ich habe 2 comboboxen (Datum & Datum_Neu), Datum dient zur navigation innerhalb der ergebnistabelle, in Datum_Neu werden die neuen daten (mehrzahl von datum), sofern vorhanden, aus der termin-tabelle geschrieben.
wenn man einen datensatz bei den ergebnissen hinzufügen will, wird direkt abgefragt, ob es neue termine gibt:

Delphi-Quellcode:
procedure TForm5.ADOTable1AfterInsert(DataSet: TDataSet);
var i,n,m : integer;
begin
  form5.qryMannschaften.Close;
  form5.qryMannschaften.SQL.Clear;
  form5.qryMannschaften.SQL.Text
  := 'SELECT datum, mannschaft_1, mannschaft_2 FROM TTermin WHERE datum NOT IN (SELECT datum from TSpielergebnisse)';
  form5.qryMannschaften.Open;
  if form5.qryMannschaften.RecordCount = 0
  then
  begin
    showmessage('Es gibt keine neuen Termine!');
    exit;
  end
  else //wenn es neue termine gibts
  begin
    n := form5.qryMannschaften.RecordCount;
    i := 0;
    form5.Datum_Neu.Clear;
    repeat
    begin
      form5.Datum_Neu.Items.Add(DateToStr(form5.qryMannschaften.FieldByName('datum').AsDateTime));
      inc(i);
      form5.qryMannschaften.Next;
    end;
    until i = n; //werden die neuen daten in die combobox geschrieben
    form5.Datum_Neu.Show; //und die combobox angezeigt
    form5.Datum.Hide;
    form5.Datum_Neu.ItemIndex := 0;
    form5.Label11.Caption := form5.qryMannschaften.FieldByName('mannschaft_1').AsString;
    form5.DBEdit9.Text := form5.qryMannschaften.FieldByName('mannschaft_1').AsString;
    form5.Label12.Caption := form5.qryMannschaften.FieldByName('mannschaft_2').AsString;
    form5.DBEdit10.Text := form5.qryMannschaften.FieldByName('mannschaft_2').AsString;
    form5.ADOTable1.Post;
nachdem es dann zur tabelle geschickt wurde, wird das neue datum in die navigations combobox (Datum) geschrieben und diese wird dann wieder angezeigt:

Delphi-Quellcode:
procedure TForm5.ADOTable1AfterPost(DataSet: TDataSet);
var m,n : integer;
begin
  m := form5.Datum.Items.Count;
  n := 0;
  repeat
  begin
    form5.Datum.ItemIndex := n;
    if form5.Datum_Neu.Text <> form5.Datum.Text
    then form5.Datum.Items.Add(form5.datum_neu.Text);
    inc(n);
  end;
  until n = m;
  form5.Datum_Neu.Hide;
  form5.Datum.Show;
end;
wenn es mehrere neue termine gab und man einen anderen auswählt als den ersten, dann werden die mannschaften aus der termintabelle aus dem datensatz, der das ausgewählte datum enthält, geholt:

Delphi-Quellcode:
procedure TForm5.Datum_NeuChange(Sender: TObject);
begin
  with form5.qryDatumNeu do
  begin
    Close;
    SQL.Clear;
    SQL.Text := 'SELECT mannschaft_1, mannschaft_2 FROM TTermin WHERE datum = '
    +form5.Datum_Neu.Text;
    Open;
  end;
  form5.ADOTable1.Edit;
  form5.DBEdit1.Text := form5.Datum_Neu.Text;
  form5.Label11.Caption := form5.qryDatumNeu.FieldByName('mannschaft_1').AsString;
  form5.DBEdit9.Text := form5.qryDatumNeu.FieldByName('mannschaft_1').AsString;
  form5.Label12.Caption := form5.qryDatumNeu.FieldByName('mannschaft_2').AsString;
  form5.DBEdit10.Text := form5.qryDatumNeu.FieldByName('mannschaft_2').AsString;
  form5.ADOTable1.Post;
end;
was nicht klappt:
- das abrufen der mannschaften, wenn zwischen mehreren neuen daten ausgewählt wird ('Synatxfehler in Zahl in Abfrageausdruck 'datum = 05.07.2004"), anscheinend kann man ein DateTime-Feld nicht mit einem String vergleichen - wie dann?

- wenn es keine neuen termine gibt, wird einfach der Text 'Datum_Neu' 3 mal hinzugefügt ()anzahl der datensätze in TTermin bzw. TSpielergebnisse)

was ich nicht kann:
- wenn ich in der combobox Datum, also der combobox zum direkten ansteuern der datensätze in der Ergebnisse-Tabelle, ein datum auswähle, wie kann ich dann in der tabelle zum entsprechenden datensatz springen? muss das wieder mittels einer query geschehen oder geht das auch eleganter?

so, ist jetzt etwas mehr geworden, aber ich hoffe ich konnte jetzt meine frage einigermaßen deutlich formulieren... :wiejetzt:

PS: das 31.12.1899 Problem hat sich irgendwie von selbst gelöst, hab nur keine ahnung wie...

MarkusB 4. Jul 2004 22:32

Re: datensätze vergleichen
 
Hi Butterflyz!

Zitat:

- das abrufen der mannschaften, wenn zwischen mehreren neuen daten ausgewählt wird ('Synatxfehler in Zahl in Abfrageausdruck 'datum = 05.07.2004"), anscheinend kann man ein DateTime-Feld nicht mit einem String vergleichen - wie dann?
StrToDate-Funktion sollte helfen.

Zitat:

- wenn es keine neuen termine gibt, wird einfach der Text 'Datum_Neu' 3 mal hinzugefügt ()anzahl der datensätze in TTermin bzw. TSpielergebnisse)
Wo der Fehler passiert weiss ich nicht, aber das kannst du bestimmt im Debug-Modus rausfinden.

Zitat:

- wenn ich in der combobox Datum, also der combobox zum direkten ansteuern der datensätze in der Ergebnisse-Tabelle, ein datum auswähle, wie kann ich dann in der tabelle zum entsprechenden datensatz springen? muss das wieder mittels einer query geschehen oder geht das auch eleganter?
Du kannst in der Tabelle nach bestimmten Sätzen auch mit Hilfe der Delphi-Funktionen suchen (das muss nicht unbedingt eine Query sprich SQL-Statement sein). Zum Beispiel: Locate, SetKey oder FindKey – schau mal in OH.

Viele Grüße
Markus
:gruebel:

Butterflyz 5. Jul 2004 15:09

Re: datensätze vergleichen
 
dankeschön, bin jetzt etwas weiter gekommen. aber was immer noch nicht klappt ist das mit dem datum:

Delphi-Quellcode:
SQL.Text := 'SELECT mannschaft_1, mannschaft_2 FROM TTermin WHERE datum = ' +(form5.datum_neu.text);
hier meckert er immer, dass die typen nicht übereinstimmen, auch wenn ich mit QuotedStr arbeite. bei StrToDate krieg ich irgendwas von wegen das es keine überladene funktion mit diesem namen gibt... aber meines erachtens nach muss es doch als string übernommen werden in das Statement, da es ja reiner text ist, also liegt es wahrscheinlich an irgendwelchen nicht gesetzten hochkommas... hab das board abgegrast, aber irgendwie finde ich da auch nichts was mir eine lösung dazu liefert...

MarkusB 5. Jul 2004 18:46

Re: datensätze vergleichen
 
Hi Butterflyz!

Jo! Bei dem Aufbau einer SQL-Anweisung (reiner Text) musst du die Funktion StrToDate nicht verwenden. Allerdings musst du auf die Anzahl der Hochkommata aufpassen - da hast du Recht!

Code:
sql.clear;
sql.add('select mannschaft_1, mannschaft_2');
sql.add(' from ttermin ');
sql.add(' where datum = ''' + form5.datum_neu.text + '''');
Viele Grüße
Markus
:gruebel:

Butterflyz 6. Jul 2004 15:57

Re: datensätze vergleichen
 
danke für die mühe, hat aber leider auch nicht geklappt :?

habs jetzt auf diese weise gelöst:

Delphi-Quellcode:
    Close;
    SQL.Clear;
    SQL.Text := 'SELECT mannschaft_1, mannschaft_2 FROM TTermin WHERE datum = :i_datum';
    prepared := true;

    with Parameters do
    begin
      ParamByName('i_datum').DataType := ftDate;
      ParamByName('i_datum').Value := StrToDate(form5.datum_neu.Text);
    end;
habe das datum also einfach als variable rausgenommen, formatiert und dann das datum aus der combobox eingelesen und übergeben. keine ahnung obs jetzt geschickt war oder nicht, jedenfalls klappts so :bouncing4:


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:20 Uhr.
Seite 1 von 2  1 2      

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