Entwickler-Ecke

Datenbanken - sql laufende Nummerierung


Tabakbrummel - Mi 30.11.11 17:09
Titel: sql laufende Nummerierung
Hallo

Ich habe Tabelle mit der Spalte LfdNr da sollen die 1 2 3... gespeichert werden und wenn ein Datensatz gelöscht wird, soll die laufende Nummerierung bleiben.
z.b
1 M
2 B
3 Z
4 T

Datensatz gelöscht
1 M
2 B
3 T

Mein Problem ist das bei diesen Code immer 1 gespeichert wird?

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
 with Q do
  begin
    Close;
    SQL.Clear;
    SQL.Add('UPDATE Tabelle SET LfdNr =');
    SQL.Add('(SELECT Count(*) FROM Tabelle as t ');
    SQL.Add('WHERE t.id < id)+1');
    ExecSQL;
//  open;
  end;


mandras - Mi 30.11.11 17:19

evtl so?


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
 with Q do
  begin
    Close;
    SQL.Clear;
    SQL.Add('UPDATE Tabelle SET LfdNr = Lfdnr-1');
    SQL.Add('WHERE t.id > '+IntToStr (<ID_DES_GELÖSCHTEN_SATZES>);
    ExecSQL;
  end;


Tabakbrummel - Mi 30.11.11 17:24

Hallo mandras

Nein Ich will erst mal das die nummerierung gespeichert wird. Aber leider kommen da nur
1
1
1.
Den Orginal Code habe von hier http://support.microsoft.com/kb/510041/de


bummi - Mi 30.11.11 17:35


Delphi-Quelltext
1:
    SQL.Add('WHERE t.id < Tabelle.id)+1');                    


funktioniert zwar, ist aber datenbanktechnisch Quark

Moderiert von user profile iconMartok: Code- durch Delphi-Tags ersetzt


mandras - Mi 30.11.11 17:54

user profile iconTabakbrummel hat folgendes geschrieben Zum zitierten Posting springen:
Hallo mandras
Nein Ich will erst mal das die nummerierung gespeichert wird. Aber leider kommen da nur


ok, so hat es bei mir funktioniert:


SQL-Anweisung
1:
2:
3:
update Tabelle 
set lfdnr = (select count(*)
 from Tabelle as t where t.lfdNr<= Tabelle.lfdNr)


Wobei ich mir bei Deinem Beispiel nicht ganz sicher bin wg. Feldern ID und LfdNr (war ID evtl. ein reserviertes Wort im Access-Beispiel von MS?) <- EDIT: ist es nicht wie ich grad kas


bummi - Mi 30.11.11 18:00

nein, ich hatte den Teil aus dem Originalbeitrag kopiert und das fehlende eingefügt, zu testen hatte ich das:

SQL-Anweisung
1:
Update lf set LFDNR = (Select Count(*) from lf lf2 where lf2.LFDNR < lf.LFDNR) + 1                    


Yogu - Mi 30.11.11 18:49

Hallo,

ist es wirklich sinnvoll, die Nummer in die Datenbank zu schreiben? Das bedeutet ja, dass bei jeder Änderung der Datenbank jeder einzelne Datensatz aktualisiert werden muss. Das birgt einerseits Performanceprobleme wenn die Tabelle etwas größer wird, und auf der anderen Seite könnte es eine korrupte Tabelle geben, wenn z.B. das Programm mal abstürzt. Wenn möglich, würde ich die Nummer eher dynamisch generieren, wenn sie benötigt wird. Aber das hängt von der Anwendung ab.

Außerdem gilt es zu überlegen, nach welcher Ordnung die Datensätze durchnummeriert werden. Einige Datenbanken würfeln hin und wieder mal ein paar Datensätze durcheinander, um Speicherlücken aufzufüllen etc. Es ist also nötig, eine ORDER BY-Klausel einzubauen.

Grüße,
Yogu


mandras - Mi 30.11.11 18:56

ups bummi,
hatten wir 2 die gleiche idee.

yogu:
Deine Einwände sind mehr als berechtigt. Solage das Daten"Ausgangsmaterial" in Ordnung ist klappt alles, aber wehe wenn nicht... (2 Lücken sind kein Problem, doppelt vergebene LfdNr schon)
Das mit dem Order By hilft jedoch nicht weiter - wenn alles ok ist ändert es nichts, wenn eine LfdNr doppelt vergeben ist hilft es auch nicht mehr.


Yogu - Mi 30.11.11 19:30

user profile iconmandras hat folgendes geschrieben Zum zitierten Posting springen:
Das mit dem Order By hilft jedoch nicht weiter - wenn alles ok ist ändert es nichts, wenn eine LfdNr doppelt vergeben ist hilft es auch nicht mehr.

Mit ORDER BY wollte nur zeigen, dass die Reihenfolge der Sortierung in allen oben genannten Queries vollkommen willkürlich ist. Meistens entspricht sie der Reihenfolge des Einfügens, manchmal aber auch nicht. Um das Problem zu lösen, sollte man die Datensätze z.B. nach Erstelldatum oder Auto-Inkrement-ID sortieren.