Entwickler-Ecke

Datenbanken - Fehler bei Query1.Post;


der Berliner - Mo 03.04.06 18:38
Titel: Fehler bei Query1.Post;
Hallo zusammen,
Ich steh mal wieder auf der Leitung

Warum bekomme ich hier:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
Query1.Active:=True;
   Query1.First;
    for i:=1 to BrAnz do begin
     Query1.Edit;
     Query1.FieldByName('SitzNr').Value:=i;
     Query1.Post;
     Query1.Next;
    end;


den Fehler:
Zitat:
Query1:eine Datenmenge die nur zum lesen ist, kann nicht geändert werden.


Beim Query kann ich doch gar nicht readonly True/False setzen oder.
Oder liegt daran das das Query Active ist?

Danke für evtl. Hilfe


BenBE - Mo 03.04.06 18:59

Wie sieht deine Query aus?
Hast Du RequestLive auf True gesetzt?


der Berliner - Mo 03.04.06 19:03

Ja hab ich ...
Mit dem Query sortiere ich eine Tabelle

SQL-Anweisung
1:
SELECT * FROM Kandidaten ORDER BY Hoechstzahl DESC                    

nach dem sortieren will ich ich in der Spalte SitzNr. Die Sitze von 1-27 durchnummerieren.

Gruß

Moderiert von user profile iconraziel: Quote- durch SQL-Tags ersetzt


raiguen - Mo 03.04.06 21:00

Moin :-)
user profile iconder Berliner hat folgendes geschrieben:
Ja hab ich ...
Mit dem Query sortiere ich eine Tabelle

SQL-Anweisung
1:
SELECT * FROM Kandidaten ORDER BY Hoechstzahl DESC                    

nach dem sortieren will ich ich in der Spalte SitzNr. Die Sitze von 1-27 durchnummerieren.
...

Punkt 1: Dieses ist eine Abfrage und die hat nur Lesecharakter! Somit ist die Fehlermeldung auch sinnvoll und richtig!!
Query1.Edit etc geht also nicht. zur Eigenschaft RequestLive siehe die OH...
Punkt 2: Wie willst Du die Sitze durchnummerieren? Nach welchem Kriterium?


jasocul - Mo 03.04.06 21:28

Ein "order by" kann bei Datenbanken dazu führen, dass auch ein RequestLive := true ignoriert wird. Das muss nicht immer sein, aber ich wäre da vorsichtig.
In diesem Fall würde ich ein Update-Statement verwenden und hinterher ein Refresh auf deine sortierte Abfrage machen.


BenBE - Mo 03.04.06 22:35

Evtl. wäre auch zu überlegen, ob man das nicht auch über ne Table machen kann und dort dann die OrderBy's vom TDataSet verarbeiten lässt.


der Berliner - Do 06.04.06 07:45

HAllo
Zitat:
Punkt 2: Wie willst Du die Sitze durchnummerieren? Nach welchem Kriterium?


Na einfach nach dem sortieren mit dem ORDER BY Größte Höchstzahl = Sitz Nr 1
nächst kleinere Höchstzahl = Sitz NR 2 usw.
bis 27 Sitze vergeben sind.
Gruß


der Berliner - Do 06.04.06 07:50

user profile iconBenBE hat folgendes geschrieben:
Evtl. wäre auch zu überlegen, ob man das nicht auch über ne Table machen kann und dort dann die OrderBy's vom TDataSet verarbeiten lässt.


Moin
Hab ich auch schon mal versuch.
Hab die Hoechtszahlen in ein ARRAY gepackt und mit nem ShellSort sortiert.
dann hatte ich das Problem das ich die Sortierten Zahlen danach nicht mehr dem Kandidaten zuordnen konnte(könnte an meiner Unwissenheit liegen)und somit die Sitzverteilung nicht mehr korrekt war.
gruß


raiguen - Fr 07.04.06 12:13

Moin :-)
Eine Möglichkeit wäre das z.B.

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:
procedure ButtonSitzverteilungClick(Sender: TObject);
var aHighScore: array of String;
    I,RecAnz: Integer;
begin
   //--auslesen
   Query1.SQL.Text := 'SELECT KandidatName, Hoechstzahl FROM Kandidaten ORDER BY Hoechstzahl DESC';
   Query1.Open;
   RecAnz := Query1.RecordCount;
   
   //--Array dimensionieren -> abhängig von Anzahl der QueryDatensätze,
   SetLength(aHighScore,RecAnz+1);

   //--Query durchlaufen und Kandidatname  eintragen
   while not Query1.Eof do
     begin
       aHighScore[Query1.RecNo] := Query1.Fields[0].AsString;
       Query1.Next;
   end;

   //--Sitznr. eintragen
   query1.Close;
   Query1.SQL.Text := 'UPDATE Kandidaten SET SitzNr=:NR WHERE kandidatname=:KN');

   for I := 1 to High(aHighScore) do
     begin
       Query1.ParamByName('KN').AsString := aHighScore[I];
       Query1.ParamByName('NR').AsInteger := I;
       Query1.ExecSQL;
   end;
...
end;


der Berliner - Fr 07.04.06 14:44

Hallo raiguen

Funktioniert gut..Danke
Ein kleines prob gibt es dennoch.
Wenn ich das prog ein paar mal Gestartet (und natürlich wieder geschlossen) habe kommt ne fehlermeldung:
"Das Feld SitzNr wurde nicht gefunden"
woran kann das liegen?

alles andere klapp die sitze werden richtig eingetragen ..muß nur noch ein bischen an der Anzahl Arbeiten. es dürfen nur 27 sein.
Das sollte aber kein prob sein.

ein Dankbare Berliner


mkinzler - Fr 07.04.06 14:56

Datenzugriffsfeld erzeugt ?


der Berliner - Fr 07.04.06 15:06

Kannst du das erklären Datenzugriffsfeld..meint du ein Grid oder sowas ?
Steh grad aufm Schlauch

und gleich noch ne Frage (Siehe Quelltext):

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:
procedure TForm1.PageControl2Change(Sender: TObject);
Var i,recanz:Integer;
var aHighScore: array of String;
begin
 if PageControl2.ActivePageIndex=0 then
 begin
   TableKandidaten.Filter:='ListeNr='+QuotedStr(IntToStr(TableListenListeNr.AsInteger));
   TableKandidaten.Filtered:=True;
  end
  else begin
   TableKandidaten.Filtered:=False;
   Query1.SQL.Text := 'SELECT KandidatName, Hoechstzahl FROM Kandidaten ORDER BY Hoechstzahl DESC';
   Query1.Open;
   RecAnz := Query1.RecordCount;

   //--Array dimensionieren -> abhängig von Anzahl der QueryDatensätze,
   SetLength(aHighScore,RecAnz+1);

   //--Query durchlaufen und Kandidatname  eintragen
   while not Query1.Eof do
     begin
       aHighScore[Query1.RecNo] := Query1.Fields[0].AsString;
       Query1.Next;
   end;

   //--Sitznr. eintragen
   query1.Close;         //<<--Hier wird Query geschlossen
   Query1.SQL.Text := 'UPDATE Kandidaten SET SitzNr=:NR WHERE kandidatname=:KN';

   for I := 1 to High(aHighScore) do
     begin
       Query1.ParamByName('KN').AsString := aHighScore[I];
       Query1.ParamByName('NR').AsFloat := I;
       Query1.ExecSQL;
   end;
   Query1.Active:=True; //<<--Hier möchte ich das die ergebnissmenge in dem DBGrid wieder angezeigt wird weil ohne Active oder open zeigt mein grid doch nischt an oder?
 end;
end;

Es kommt aber der Fehler "Fehler beim Erstellen des Cursor-Handle" :(
Ich weiß nich mehr weiter. :nixweiss:


mkinzler - Fr 07.04.06 15:13

Entweder eine Komponente, die mit dem DataSet verknüpft ist oder ein durch Doppelklick auf das DataSet erzeugtes Zugriffsfeld (TField).


der Berliner - Fr 07.04.06 15:22

jepp...siehe oben ist ein DBGrid


mkinzler - Fr 07.04.06 15:24

Ich würde für den Update-Vorgang eine eigene Query-Komponenete nehmen oder ein gleich TUpdateSQL. Sonst mußt du nach dem Update die ursprüngliche Select-Abfrage wieder in den Query eintragen und erneut ausführen.


der Berliner - Fr 07.04.06 15:34

Hey cool danke..
Der Tipp war Goldrichtig..
Die Betriebsräte werden Euch ewig danken.