Autor |
Beitrag |
Shorti
Hält's aus hier
Beiträge: 10
|
Verfasst: Di 14.09.10 17:28
Hallo zusammen,
ich bin dabei mir eine Funktion zu schreiben, mit der man innerhalb einer Firebird-Datenbank einen Datensatz duplizieren kann. Funktioniert soweit auch. Nur wenn ich danach die erste Spalte neu durchnummerieren will, wird die neue Nr. vom duplizierten Datensatz nicht in die Datenbank übernommen. Ich finde einfach den Fehler nicht, bitte helft mir.
Hier der Code:
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:
| procedure DatensatzDuplizieren(Query:TZQuery;Tabelle,SQLFilter:String); var i : Integer; a : Integer; b : Integer; s : String; s1: String; begin if (Query.FieldByName('Rangfolge').AsString <> '') then begin if (Query.FieldByName('Rangfolge').AsInteger >= 1) then begin s1:= ''; i := Query.RecNo; s := Query.FieldByName('Rangfolge').AsString;
for a := 1 to Query.FieldCount - 1 do begin s1 := s1 + Query.Fields[a].FieldName + ','; end; Delete(s1,Length(s1),1); QueryExec(Query,'INSERT INTO '+Tabelle+' ('+s1+') SELECT '+s1+' FROM ' +Tabelle+' WHERE Rangfolge = '+s,False); QueryExec(Query,'SELECT '+SQLFilter+' FROM '+Tabelle,True); Query.Last; Query.Edit; Query.FieldByName('Rangfolge').AsString := s; Query.Post; QueryExec(Query,'SELECT '+SQLFilter+' FROM '+Tabelle+' ORDER BY Rangfolge',True);
Query.First; a := 0; while not Query.Eof do begin inc(a); Query.Edit; Query.FieldByName('Rangfolge').AsInteger := a; Query.Post; Query.Next; end; QueryExec(Query,'SELECT '+SQLFilter+' FROM '+Tabelle,True); Query.RecNo := i; end; end; end; |
Nach dem Aufruf "QueryExec(Query,'SELECT '+SQLFilter+' FROM '+Tabelle,True);" der Tabelle sieht man, das Quell- und Zielzeile immer noch die selbe Nummer in Spalte "Rangfolge" stehen haben. Ich bin ratlos.
MfG Shorti
|
|
Sinspin
      
Beiträge: 1335
Erhaltene Danke: 118
Win 10
RIO, CE, Lazarus
|
Verfasst: Di 14.09.10 18:00
Kann es sein dass das Feld "Rangfolge" Autoinc Ist? Warum kopierst du die "Rangfolge" nicht gleich mit allen anderen Feldern mit? Das hat doch den gleichen Effekt als wie wenn du es nachher machst, zudem vermeidest du Fehler.
Fehler in den Ausschnitt von Zeile 24 bis 27: Da hast du eine schöne Fehlerquelle drinne die zu Fehlern führt wenn mehrere leute zur gleichen Zeit damit Einträge duplizieren.
_________________ Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
|
|
Shorti 
Hält's aus hier
Beiträge: 10
|
Verfasst: Mi 15.09.10 08:08
Danke erstmal für die schnelle Reaktion.
Zitat: | Kann es sein dass das Feld "Rangfolge" Autoinc Ist? |
Da ich noch nicht lange mit Datenbanken arbeite, musst du mir mal auf die Sprünge helfen. Wenn mit "Autoinc" ein automatisches hochzählen gemeint ist, kann ich ganz klar nein sagen.
Zitat: | Warum kopierst du die "Rangfolge" nicht gleich mit allen anderen Feldern mit? |
Habe ich erst versucht, aber durch die Zeile 19/20 wurde eine Endlosschleife ausgelöst, da aus derselben Tabelle mit derselben Bedingung "WHERE Rangfolge = '+s" wahrscheinlich das gleiche eingefügt wurde.
Zitat: | Fehler in den Ausschnitt von Zeile 24 bis 27: Da hast du eine schöne Fehlerquelle drinne die zu Fehlern führt wenn mehrere leute zur gleichen Zeit damit Einträge duplizieren. |
Wie würdest du so etwas lösen?
MfG Shorti
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Mi 15.09.10 11:00
Etwa in der Art ...
insert into Sort ([text],rangfolge) Select [Text],(Select max(rangfolge) + 1 from Sort) from Sort where rangfolge=10;
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Mi 15.09.10 11:19
einen hab ich noch zu resortieren, geht unter MSSQL
keine Ahnung ob Deine DB-Engine das unterstützt
Update Sort set Rangfolge=1 where Rangfolge = (Select min(Rangfolge) from Sort)
While (Select max(Rangfolge) from Sort)<>(Select Count(*) from Sort)
begin
update Sort set Rangfolge=(Select max(Rangfolge) + 1 from Sort s where s.Rangfolge<Sort.Rangfolge) where Rangfolge<>1
end
|
|
Shorti 
Hält's aus hier
Beiträge: 10
|
Verfasst: Mi 15.09.10 14:28
Hallo Bummi,
durch deine Anregung der Sortierung mit SQL, habe ich meine Strategie nochmal überdacht und siehe da, es hat sogar etwas gebracht. Der Code ist auch etwas kürzer geworden.
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:
| procedure DatensatzDuplizieren(Query:TZQuery;Tabelle,SQLFilter:String); var i : Integer; a : Integer; b : Integer; s : String; s1: String; begin if (Query.FieldByName('Rangfolge').AsString <> '') then begin if (Query.FieldByName('Rangfolge').AsInteger >= 1) then begin s1:= ''; i := Query.RecNo; s := Query.FieldByName('Rangfolge').AsString;
for a := 1 to Query.FieldCount - 1 do begin s1 := s1 + Query.Fields[a].FieldName + ','; end; Delete(s1,Length(s1),1);
QueryExec(Query,'UPDATE '+Tabelle+' SET Rangfolge = Rangfolge + 1 WHERE Rangfolge > '+s,False); QueryExec(Query,'INSERT INTO '+Tabelle+' (Rangfolge,'+s1+ ') SELECT '+s+'+1,'+s1+ ' FROM '+Tabelle+' WHERE Rangfolge = '+s,False); QueryExec(Query,'SELECT '+SQLFilter+' FROM '+Tabelle+' ORDER BY Rangfolge',True); Query.RecNo := i; end; end; end; |
Vielen Dank nochmal dafür.
Aber wenn mir jetzt noch jemand erklären könnte, warum bei dem alten Code das Nummerieren der neu eingefügten Zeile nicht in die Datenbank übernommen wurde, wäre ich wunschlos glücklich. Das lässt mir keine Ruhe.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| Query.First; a := 0; while not Query.Eof do begin inc(a); Query.Edit; Query.FieldByName('Rangfolge').AsInteger := a; Query.Post; Query.Next; end; QueryExec(Query,'SELECT '+SQLFilter+' FROM '+Tabelle,True); Query.RecNo := i; |
Nehmen wir mal an, es gibt Rangfolge 1-4. Ich markiere Nummer 2 und dupliziere mit "INSERT INTO", vergebe der Zeile vorläufig auch die Nummer 2 mit "Query.FieldByName('Rangfolge').AsInteger := 2;", Sortiere dann nach Rangfolge. Nun ist schonmal im Query alles in der richtigen Reihenfolge. Nun beginnt die Funktion wie oben zu sehen. Die Schleife funktioniert auch, es wird alles richtig nummeriert, aber nur im Query. Werden nun die Daten mit "QueryExec(..." neu aufgerufen, sieht man, das die neue Zeile immer noch die Nummer 2 hat. (Wie vorhin vergeben) WARUM???
MfG Shorti
|
|
|