Entwickler-Ecke

Datenbanken - Query-Problem


D. Annies - Mo 17.08.09 20:58
Titel: Query-Problem
Hi, Delpher,
die folgende Query ergibt beim ersten Aufruf eine Fehlermeldung:
Parameter klassenstufe nicht gefunden


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
procedure TForm2.sortiertnachKlassen1Click(Sender: TObject);
var n : smallint;
begin
  stringgrid1.RowCount := 2;
  showmessage('Die Klassenstufe '+ ListBox1.Items[ListBox1.itemindex]+ ' von '+
                DaMod1.ADOTbMerge.TableName+ ' wird sortiert');
  DaMod1.ADOQyMerge.Close;
    DaMod1.ADOQyMerge.SQL.Text :=
      'select geschlecht, punkte, klasse, name, vorname from '+ DaMod1.ADOTbMerge.TableName +
      ' where (klasse like :klassenstufe) and (Punkte > 0) '+
      'order by geschlecht, Klasse, punkte desc, name, vorname';
    DaMod1.ADOQyMerge.Parameters.ParamByName('klassenstufe').value := ListBox1.Items[ListBox1.itemindex]+'%';
  DaMod1.ADOQyMerge.Open;  //showmessage(inttostr(DaMod1.ADOQyMerge.RecordCount));

  if DaMod1.ADOQyMerge.recordcount > 0 then
  begin
    DaMod1.ADOQyMerge.First;
    n := 1;
    repeat
      stringgrid1.Cells[0,n] := inttostr(n);
      stringgrid1.Cells[1,n] := DaMod1.ADOQyMerge.fieldbyname('Punkte').asstring;
      stringgrid1.Cells[2,n] := DaMod1.ADOQyMerge.fieldbyname('Geschlecht').asstring;
      stringgrid1.Cells[3,n] := DaMod1.ADOQyMerge.fieldbyname('Klasse').asstring;
      stringgrid1.Cells[4,n] := DaMod1.ADOQyMerge.fieldbyname('Name').asstring;
      stringgrid1.Cells[5,n] := DaMod1.ADOQyMerge.fieldbyname('Vorname').asstring;
      DaMod1.ADOQyMerge.Next; inc(n);
    until n = DaMod1.ADOQyMerge.RecordCount+1;
    stringgrid1.RowCount := n;
    label2.Caption := (Sender as tmenuitem).Caption;
  end
  else showmessage('Abfrage ist leer / falsche Tabelle');
end;


Dann rufe ich eine andere Query auf, die alle Datensätze sortiert ausgibt.

Dann klappt der Aufruf der obigen Query ohne Fehlermeldung

Warum kommt erst die Fehlermeldung??

Danke für Hilfe,
Detlef


Moderiert von user profile iconNarses: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am Mo 17.08.2009 um 22:43


D. Annies - Mi 19.08.09 09:39

Leider habe ich noch keine Antwort erhalten - ist ja auch so nicht vernünftig - aber genau so, wie oben geschildert, passiert es.

Hier ist zur Ergänzung der Code, der alle Datensätze ausgibt:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
procedure TForm2.dieSchulbestenca5wm1Click(Sender: TObject);
var n, k : smallint;
begin
  for n := 0 to stringgrid1.ColCount - 1 do
    for k := 1 to stringgrid1.RowCount - 1 do
      stringgrid1.Cells[n,k] := '';
  stringgrid1.RowCount := 2;
  n := 1;
  DaMod1.ADOQyMerge.Connection := DaMod1.ADOConnection1;  //dbase
  DaMod1.ADOQyMerge.close;
    DaMod1.ADOQyMerge.SQL.Text :=                             // fn = gestutzter OD1.Filename
      'select punkte, geschlecht, klasse, name, vorname from '+ DaMod1.ADOTbMerge.TableName +
        ' where (geschlecht = ''w'') and (punkte > 0) ' +
      'order by punkte desc';
  DaMod1.ADOQyMerge.open; showmessage(inttostr(DaMod1.ADOQyMerge.recordcount));
  if DaMod1.ADOQyMerge.recordcount > 0 then
  begin
    DaMod1.ADOQyMerge.First;
    k := 0;
    stringgrid1.Cells[0,n] := inttostr(n);
    stringgrid1.Cells[1,n] := DaMod1.ADOQyMerge.fieldbyname('punkte').asstring;
    stringgrid1.Cells[2,n] := DaMod1.ADOQyMerge.fieldbyname('Geschlecht').asstring;
    stringgrid1.Cells[3,n] := DaMod1.ADOQyMerge.fieldbyname('Klasse').asstring;
    stringgrid1.Cells[4,n] := DaMod1.ADOQyMerge.fieldbyname('Name').asstring;
    stringgrid1.Cells[5,n] := DaMod1.ADOQyMerge.fieldbyname('Vorname').asstring;
    inc(n); inc(k);
    while (not DaMod1.ADOQyMerge.Eof) and (k < 5do    // nicht repeat!
    begin
      DaMod1.ADOQyMerge.Next;
      if DaMod1.ADOQyMerge.FieldByName('punkte').AsInteger = strtoint(stringgrid1.Cells[1,n-1]) then
      begin
        stringgrid1.Cells[0,n] := inttostr(n);
        stringgrid1.Cells[1,n] := DaMod1.ADOQyMerge.fieldbyname('punkte').asstring;
        stringgrid1.Cells[2,n] := DaMod1.ADOQyMerge.fieldbyname('Geschlecht').asstring;
        stringgrid1.Cells[3,n] := DaMod1.ADOQyMerge.fieldbyname('Klasse').asstring;
        stringgrid1.Cells[4,n] := DaMod1.ADOQyMerge.fieldbyname('Name').asstring;
        stringgrid1.Cells[5,n] := DaMod1.ADOQyMerge.fieldbyname('Vorname').asstring;
      end
      else
      if DaMod1.ADOQyMerge.FieldByName('punkte').AsInteger < strtoint(stringgrid1.Cells[1,n-1]) then
      begin
        stringgrid1.Cells[0,n] := inttostr(n);
        stringgrid1.Cells[1,n] := DaMod1.ADOQyMerge.fieldbyname('punkte').asstring;
        stringgrid1.Cells[2,n] := DaMod1.ADOQyMerge.fieldbyname('Geschlecht').asstring;
        stringgrid1.Cells[3,n] := DaMod1.ADOQyMerge.fieldbyname('Klasse').asstring;
        stringgrid1.Cells[4,n] := DaMod1.ADOQyMerge.fieldbyname('Name').asstring;
        stringgrid1.Cells[5,n] := DaMod1.ADOQyMerge.fieldbyname('Vorname').asstring;
        inc(k);
      end;
      inc(n);    // showmessage('k = '+ inttostr(k));    //DaMod1.ADOQyMerge.Next;
    end;         // until (k = 5);
  end;

  DaMod1.ADOQyMerge.Close;
    DaMod1.ADOQyMerge.SQL.Text :=                             // fn = gestutzter OD1.Filename
      'select punkte, geschlecht, klasse, name, vorname from '+ DaMod1.ADOTbMerge.TableName +
        ' where (geschlecht = ''m'') and (punkte > 0) ' +
      'order by punkte desc';
  DaMod1.ADOQyMerge.open; showmessage(inttostr(DaMod1.ADOQyMerge.recordcount));
  if DaMod1.ADOQyMerge.recordcount > 0 then
  begin
    DaMod1.ADOQyMerge.First;
    k := 0;
    stringgrid1.Cells[0,n] := inttostr(n);
    stringgrid1.Cells[1,n] := DaMod1.ADOQyMerge.fieldbyname('punkte').asstring;
    stringgrid1.Cells[2,n] := DaMod1.ADOQyMerge.fieldbyname('Geschlecht').asstring;
    stringgrid1.Cells[3,n] := DaMod1.ADOQyMerge.fieldbyname('Klasse').asstring;
    stringgrid1.Cells[4,n] := DaMod1.ADOQyMerge.fieldbyname('Name').asstring;
    stringgrid1.Cells[5,n] := DaMod1.ADOQyMerge.fieldbyname('Vorname').asstring;
    inc(n); inc(k);
    while (not DaMod1.ADOQyMerge.Eof) and (k < 5do
    begin
      DaMod1.ADOQyMerge.Next;
      if DaMod1.ADOQyMerge.FieldByName('punkte').AsInteger = strtoint(stringgrid1.Cells[1,n-1]) then
      begin
        stringgrid1.Cells[0,n] := inttostr(n);
        stringgrid1.Cells[1,n] := DaMod1.ADOQyMerge.fieldbyname('punkte').asstring;
        stringgrid1.Cells[2,n] := DaMod1.ADOQyMerge.fieldbyname('Geschlecht').asstring;
        stringgrid1.Cells[3,n] := DaMod1.ADOQyMerge.fieldbyname('Klasse').asstring;
        stringgrid1.Cells[4,n] := DaMod1.ADOQyMerge.fieldbyname('Name').asstring;
        stringgrid1.Cells[5,n] := DaMod1.ADOQyMerge.fieldbyname('Vorname').asstring;
      end
      else
      if DaMod1.ADOQyMerge.FieldByName('punkte').AsInteger < strtoint(stringgrid1.Cells[1,n-1]) then
      begin
        stringgrid1.Cells[0,n] := inttostr(n);
        stringgrid1.Cells[1,n] := DaMod1.ADOQyMerge.fieldbyname('punkte').asstring;
        stringgrid1.Cells[2,n] := DaMod1.ADOQyMerge.fieldbyname('Geschlecht').asstring;
        stringgrid1.Cells[3,n] := DaMod1.ADOQyMerge.fieldbyname('Klasse').asstring;
        stringgrid1.Cells[4,n] := DaMod1.ADOQyMerge.fieldbyname('Name').asstring;
        stringgrid1.Cells[5,n] := DaMod1.ADOQyMerge.fieldbyname('Vorname').asstring;
        inc(k);
      end;
      inc(n);      // showmessage('k = '+ inttostr(k));   //DaMod1.ADOQyMerge.Next;
    end;           // until (k = 5) or DaMod1.ADOQyMerge.eof;
  end;
  stringgrid1.RowCount := n;
  label2.Caption := (Sender as tmenuitem).Caption;
end;


Wer hat da bessere Augen als ich? Irgendetwas muss doch verstellt werden/sein, sodass es erst nicht funktioniert
(Fehlermeldung: EDatabasaError Parameter klassenstufe nicht gefunden)
und dann, nach dem Aufruf dieser Prozedur, klappt der obige (der erste) Prozeduraufruf.

Danke für Hilfe,
Detlef


mkinzler - Mi 19.08.09 09:54

Ersetze den Doppepunkt mal durch ?


Delete - Mi 19.08.09 10:23

Ersetze auch gleich mal die Logik ;)

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
Query.Open;
while not Query.EOF do
  begin
    ... 
    Query.Next;
  end;

So musst Du weder den RecordCount erfragen noch alles doppelt machen.


D. Annies - Mi 19.08.09 10:37

Hi, Markus, welchen Doppelpunkt bitte?
Detlef


mkinzler - Mi 19.08.09 11:07

Beim Parameter


Sinspin - Mi 19.08.09 11:10

An dem Doppelpunkt liegt das nicht. (Allgemein nicht an den Doppelpunkten, ging ja bisher auch immer damit)
Kennt die ADOQuery sowas wie AutoPepare? Wenn ja, muss das true sein. Wenn nicht musst du vor dem Öffnen der Query Prepare aufrufen.
So ein Problem mit unbekannten Parametern hattest du schonmal vor einiger Zeit!


D. Annies - Mi 19.08.09 20:06

Hi, sinspin

nun, daran liegt es leider auch nicht: ich habe im Code und im OI (nacheinander) prepared auf true gesetzt, aber ohne Wirkung, es ist noch wie vorher.

:roll: :roll: Detlef


D. Annies - Do 20.08.09 08:51

Hi, Delpher,

DeddyH schrieb in diesem Thread, ich solle doch die Logik ersetzen, dann muss ich nicht alles doppelt machen. Nun, ich will ja die besten 5 Mädchen und (danach) die besten 5 Jungen ausgeben. Geht das in einem SQL-Befehl? Ich habe es nicht geschafft.

Gruß, Detlef


Delete - Do 20.08.09 09:27

Das müsste gehen, zur Not über eine UNION.


D. Annies - Do 20.08.09 09:34

Jo, gute Idee, das prüfe ich mal - die andere "Seltsamheit" besteht weiterhin ...
Detlef


D. Annies - Do 20.08.09 10:19

So, ich bin noch einmal alle Tipps von euch durchgegangen.

Es fehlte vor der "besagten" Query die Connection!!


Delphi-Quelltext
1:
DaMod1.ADOQyMerge.Connection := DaMod1.ADOConnection1;  //dbase                    


In der zweiten stand dieser Befehl und so war die Connection für die "besagte" vorhanden, nachdem die zweite Query einmal aufgerufen war. Wo sollte ich denn am besten die Connection (einmal für alle) aufrufen?

Grüße von :D Detlef


Delete - Do 20.08.09 11:15

Erstell Dir doch einfach eine Methode, die die Einstellungen automatisch vornimmt. Nach dem DRY-Prinzip (Don' t repeat yourself) rufst Du nun nur noch diese Methode auf (falls eine Einstellung per OI zur Designtime nicht möglich ist).


D. Annies - Do 20.08.09 12:34

Also eine Prozedur, vielleicht namens Init, die dann von OnShow aufgerufen wird?


Delete - Do 20.08.09 13:22

Eine Routine mit einem Namen Deiner Wahl, die dann aufgerufen wird, wenn Du sie brauchst ;)


D. Annies - Do 20.08.09 21:56

Okwe!
bis denne, Det