Entwickler-Ecke

Datenbanken - ID herauslesen und ändern


sabi_14 - Do 24.04.08 08:53
Titel: ID herauslesen und ändern
Hallo,
ich arbeite an einer Notizverwaltung und möchte jetzt eine neue Notiz erstellen.
Dies funktioniert soweit auch, bis auf dies mit der id.
ich versuche die id's herauszulesen und möchte dann den grössten Wert, welcher vorhanden ist nehmen
und diesen dann um eins erhöhen.
Aber es kommt immer eine Fehlermeldung.
Könnte vielleich mal jemand meinen Code durchsehen und mir sagen was falsch ist?
(bin noch Anfänger.)


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure TfrmNeueNotiz.btnSpeichernClick(Sender: TObject);
var
  id: Integer;
  dbid: Integer;
begin
  tblNotiz.Edit;
  tblNotiz.Append;
  tblNotiz.FieldByName('DATUM').AsString:=dateToStr(now);
  tblNotiz.FieldByName('ERLEDIGT').AsString:='False';
  dbid:=tblNotiz.FieldByName('ID').AsInteger;
  id:=MaxIntValue(dbid)+ 1;
  tblNotiz.FieldByName('ID').asInteger:=id;
  tblNotiz.FieldByName('TITEL').AsString:=edtTitel.Text;
  tblNotiz.FieldByName('TEXT').AsString:=edtText.Text;
  tblNotiz.Post;
  Close;
end;

Danke schomal im voraus.
grüsse
sabi

Moderiert von user profile iconGausi: Delphi-Tags hinzugefügt


vladi - Do 24.04.08 09:08

Also wenn ich das richtig verstehe möchtest du mit der Zeile : tblNotiz.FieldByName('ID').asInteger:=id; Die ID wieder in die DB schreiben..

So funktioniert das aber nicht... Du musst die ID per Insert-Query resp. Update-Query in die DB schreiben.
Das kannst du beispielsweise mit einem ADOCommand machen:


Quelltext
1:
2:
DeinADOCommand.CommandText := deinSQLStatement;
DeinADOCommand.Execute;                    //Führt das Query aus



Das Statement könnte so aussehen: 'UPDATE tblNotiz SET ID = '+ id +' WHERE ID = ' + id - 1 + ';'

Wie liesst du denn die DB aus?

Greez Vladi


sabi_14 - Do 24.04.08 09:17

Hallo,
also, denn ersten Teil hast du richtig erfasst.
ich verstehe nicht, warum dass bei der id nicht gehen soll, bei den anderen Daten funktioniert das ja auch.

Kann ich ADO Komponenten verwenden, wenn ich sonst alles mit Interbase habe?
Kommt das auf die DB an?

Wie meinst du das mit der DB herauslesen?

Grüsse
sabi

(P.S. Sorry für die blöden Fragen, aber ich kenn mich noch nicht gut aus.)


mkinzler - Do 24.04.08 09:25

Ganz einfach, weil man duie ID eines datensatzes nie und nimmer Ändern sollte!!!!


vladi - Do 24.04.08 09:28

Also wenn du Interbase benutzt würde ich dabei bleiben.... Leider kenne ich diese Komponente nicht... (Bin auch erst am 2ten Delphi-Projekt^^).

Welche daten schreibst du den noch in die DB? Ich sehe nur die Zeile tblNotiz.FieldByName('ID').asInteger:=id; hinter der ich die Absicht vermute etwas in die DB zu schreiben.

Du musst die Daten ja von irgendwo haben. Sprich aus einer DB ausgelesen haben.

Die Datenbank spielt beim ConnectionString eine Rolle... Aber wie gesagt ich kann nur von der ADO komponente sprechen weil ich Interbase nicht kenne...

Edit: ich hab kurz gegooglet und bin auf ein Tutorial für Interbase gestossen: http://www.delphi-treff.de/tutorials/datenbank-tutorials/win32/interbase/page/5/

Greez Valdi


Delete - Do 24.04.08 09:34

Lass die ID in Ruhe. Das sollte ein autoincrement Feld sein, welches bei einem neuen Datensatz automatisch erhöht wird.


sabi_14 - Do 24.04.08 09:37

Also, es ist so, dass ich mit dieser Prozedure einen neuen Datensatz in der Datenbank
erstellen möchte. Da ich auf dem Form nur die beiden Felder Titel und Text habe, sollen
die anderen Daten automatisch übergeben werden. Und dies macht es auch.
Als erstes übergebe ich das aktuelle Datum, dann übergebe ich den booleanwert fals für
das Feld erledigt (dieses Feld kann man auf True setzten, aber nur im Bearbeiter Form,
dies funktioniert.) Dann übergebe ich noch die eingegebenen Strings von Titel und Text.
Dies funktioniert alles bis hierhin. (wenn ich die id von Hand ändere.)
Jetzt möchte ich aber, dass die Prozedure mir die vorhandenen id's aus der Datenbank
herausliest. Von dieser Liste den grössten Integer herausnimmt und dann diesen um
eins erhöht. Wenn dies gemacht ist, soll es diese neue ID in die Datenbank schreiben
und zwar als id für den neuen Datensatz.
Versteht ihr jetzt?
Irgendwie hat es aber ein Problem damit den grössten Wert zu bekommen, oder ich weiss
nicht, wie ich eine ganze Liste der ID aus der Datenbank bekomme.

Grüsse
Sabi


sabi_14 - Do 24.04.08 09:39

Und wie kann ich ein solches autoincrement Feld erstellen?
In der Datenbank habe ich schon definiert, dass die ID not null
und ein primary key und ein Integer ist.
Habe ich denn da etwas vergessen?
grüsse
Sabi


zuma - Do 24.04.08 09:43

nimm einen zweiten query, den du mit folgendem Select-befehl benutzt
Select max(id) as hoechsteID from tblNotiz
der liefert dir dann die höchste ID zurück und den wert brauchst du dann nur noch um 1 erhöhen und in deiner methode setzen.


mkinzler - Do 24.04.08 09:53

Zitat:
Und wie kann ich ein solches autoincrement Feld erstellen?

Kommt auf das verwendete DBMS an.


sabi_14 - Do 24.04.08 10:28

Hey,
DANKE für eure Hilfe.
Es funktioniert jetzt.

Grüesse und noch einen schönen Tag.
Sabi


baka0815 - Mi 07.05.08 17:56
Titel: Re: ID herauslesen und ändern
Auch wenn's jetzt klappt.

Die folgenden Zeilen hast du falsch verstanden:
user profile iconsabi_14 hat folgendes geschrieben:

Delphi-Quelltext
1:
2:
3:
  dbid:=tblNotiz.FieldByName('ID').AsInteger;
  id:=MaxIntValue(dbid)+ 1;
  tblNotiz.FieldByName('ID').asInteger:=id;


Du nimmst die ID des aktuellen Datensatzes und keinesfalls die größte.
Wenn du die aktuelle ID jetzt um 1 erhöhst, dann kann es natürlich sein, dass diese schon vergeben ist.

Verwende für sowas, wenn möglich, eine auto-increment Spalte. Wenn das die Datenbank nicht unterstützt gibt es vieleicht trotzdem datenbankseitig Hilfen (bei Oracle z.B. Trigger und Sequenzen).

Beim Anlegen eines neuen Datensatzes die höchste ID zu holen, 1 zu addieren und den neuen Datensatz mit der ID anlegen sollte zwar in den meisten Fällen funktionieren, wenn du dann jedoch mit mehreren Nutzern gleichzeitig arbeitest könnte es vorkommen, dass beide die selbe ID zugewiesen bekommen und dann kann einer der beiden nicht speichern.

Um das ganze trotzdem über die größte ID zu machen müßtest du ein SQL wie das folgende nutzen:

SQL-Anweisung
1:
select max(id) from notiz