![]() |
Datenbank: Firebird • Version: 2 • Zugriff über: FlameRobin
Int-Feld nachträglich auf autoincrement setzen
Moin,
ich möchte ein int-Feld (ID) in einer Tabelle nachträglich auf Autoincrement setzen und mache das mit dem FlameRobin-Dialog. Dort kann ich einen Generator erzeugen oder auswählen und einen Trigger erzeugen. Das sieht alles richtig aus, wenn ich Daten übergebe schlägt es aber fehl:
Code:
Klappt das nachträgliche Ändern nicht oder passt meine Übergabe nicht? Wenn ich die Autoincrement-Spalte weglasse, bekomme ich ein mismatch beim parametercount.
insert into MEASURED_DATA values (ID,1,2,3,4)
Grüße, Messie |
AW: Int-Feld nachträglich auf autoincrement setzen
Du solltest die Namen der Felder mit angeben, sonst weiß ja keiner was wo rein soll :zwinker:
[add] ![]() ![]() |
AW: Int-Feld nachträglich auf autoincrement setzen
Du musst in dem Fall die Spalten explizit angeben:
Code:
insert into MEASURED_DATA (spalte_a, spalte_b, spalte_c, spalte_d) values (1,2,3,4)
|
AW: Int-Feld nachträglich auf autoincrement setzen
Moin,
klappt so, danke! Ich kann aber tatsächlich
Code:
die Einträge auch ohne Bezeichner erzeugen, dabei wird dann aber wohl die autoincrement-Variable überschrieben.
insert into MEASURED_DATA values (35,1,2,3,4)
Wahrscheinlich schreibt außer mir niemand immer die ganze Zeile :wink: Ist eben ein Umbau eines Programms von Dateien auf Datenbank. Und da habe ich die ganze Zeile halt da... Grüße, Messie |
AW: Int-Feld nachträglich auf autoincrement setzen
Es wird nicht nur das Autoinc überschrieben (es wird gesetzt und nicht automatisch bestimmt), sondern rate mal was passiert, wenn sich mal das Datenbankschema ändert und die Felder in einer anderen Reihenfolge vorliegen. :wink:
Vielleicht ist es keine schlechte Idee immer die Feldnamen anzugeben. |
AW: Int-Feld nachträglich auf autoincrement setzen
Ob der "AutoInc"-Wert überschrieben wird, hängt davon ab, wie der zugehörige Trigger aussieht ;)
|
AW: Int-Feld nachträglich auf autoincrement setzen
Zudem muss man den Initialwert anpassen, sonst gibt es eine Kollision
|
AW: Int-Feld nachträglich auf autoincrement setzen
Zitat:
Code:
soetwas?
Autoincint=max(altespalte)+1
Gruß K-H |
AW: Int-Feld nachträglich auf autoincrement setzen
Klar, initial steht der auf 1, das kann nur gut gehen, wenn noch keine Daten vorhanden sind. Falls doch, muss er halt auf Maximalwert + 1 gesetzt werden.
|
AW: Int-Feld nachträglich auf autoincrement setzen
SQL-Code:
set generator <GeneratorName> to <NächsterWert>;
|
AW: Int-Feld nachträglich auf autoincrement setzen
Zitat:
Dabei muss man insbesondere die AutoInc-Felder weglassen, denn diese Felder werden ja autom. vom DBMS bzw. vom Trigger befüllt. Das Blöde an AutoInc-Feldern ist dass man den vergebenen Wert im Nachhinein nur schwer feststellen kann. Solange dein Programm den neuen AutoInc-Wert nach dem Insert nicht benötigt ist das aber ok. Beim SQL-Server kann man den letzten Wert mit SELECT @@Identity abfragen; aber das ist Gemurkse. |
AW: Int-Feld nachträglich auf autoincrement setzen
Das gilt so nicht für FireBird, denn hier wird der AutoInc über einen Generator(Sequenz) und einen Trigger implementiert.
|
AW: Int-Feld nachträglich auf autoincrement setzen
Zitat:
Unter Firebird / InterBase Stored Procedure SQL:
Code:
Autoincint = GEN_ID(GENERATORNAME, 1);
|
AW: Int-Feld nachträglich auf autoincrement setzen
Zitat:
Zitat:
![]() |
AW: Int-Feld nachträglich auf autoincrement setzen
Zitat:
Eine Einschränkung: Wenn ein Trigger einen Insert macht würde mit SELECT @@Identity die ID des vom Trigger inserteten Datensatzes zurückkommen. Um auch dieses "Problem" zu umgehen gibt es ![]() Mit dieser wird wirklich nur die letze ID der eigenen Session (und des eigenen scopes) zurückgegeben. ![]() Gut hab ich mich mal wieder mit Thema beschäftigt. Scheinbar ist spurlos an mir vorbeigegangen dass es seit MSSQLSERVER 2005 ![]() |
AW: Int-Feld nachträglich auf autoincrement setzen
Zitat:
das wüsste ich gerne mal genauer. Ich habe für das Inkrementieren einen Generator und einen Trigger. Ich hätte vom Bezeichner her gedacht, dass hinter dem Generator die Prozedur zur Berechnung des nächsten Index steht. Der ist aber leer, dafür finde ich das im Trigger. Ist der Generator nur eine Variable oder ein Flag, die auf den Trigger verweisen? Dann bräuchte man den doch gar nicht. Grüße, Messie wie immer schon mal vorab sorry für die dämlichen Fragen |
AW: Int-Feld nachträglich auf autoincrement setzen
Richtig, ein Generator (auch Sequence genannt) ist im Prinzip nur ein Zähler.
Man kann dann mithilfe eines Triggers im Falle eines Inserts den nächsten Wert auslesen und diesen als ID eintragen. Die meisten Administratorprogramme legen diesen Trigger so an, dass das nur passiert, wenn ID = null ist. Es bleibt dir aber selbst überlassen, wie du deinen Trigger programmiert. Man kann z.B. auch komplett auf den Generator verzichten und die IDs als ![]() Es stehen einem also alle Türen offen... Man ist damit sehr flexibel. Man kann über so einen Trigger auch noch viel mehr sinnvolle Sachen hinterlegen, wie z.B. ein logging -oder Sperrsystem. |
AW: Int-Feld nachträglich auf autoincrement setzen
Was ich meinte: häufig sieht der Trigger ja so aus
Delphi-Quellcode:
Wenn man da also beim INSERT einen Wert für das "AutoInc"-Feld angibt, wird der genommen, ansonsten aus dem Generator gezogen. Das kann aber später zu Kollisionen führen, daher nehme ich immer den automatisch generierten Wert, egal ob ein gewünschter angegeben wurde oder nicht.
set term !! ;
CREATE TRIGGER T1_BI FOR T1 ACTIVE BEFORE INSERT POSITION 0 AS BEGIN if (NEW.ID is NULL) then NEW.ID = GEN_ID(GEN_T1_ID, 1); END!! set term ; !!
Delphi-Quellcode:
set term !! ;
CREATE TRIGGER T1_BI FOR T1 ACTIVE BEFORE INSERT POSITION 0 AS BEGIN NEW.ID = GEN_ID(GEN_T1_ID, 1); END!! set term ; !! |
AW: Int-Feld nachträglich auf autoincrement setzen
Zitat:
|
AW: Int-Feld nachträglich auf autoincrement setzen
Das klingt aber nach falscher Reihenfolge, oder? Ich könnte mir höchstens vorstellen, dass bei einer Migration so etwas auftreten kann, aber in dem Fall würde ich sowieso alle Trigger usw. deaktivieren, bis die Daten importiert sind, und dann erst die Generatoren auf den richtigen Wert bringen und die Trigger scharfschalten.
|
AW: Int-Feld nachträglich auf autoincrement setzen
Da mag es Vorkommen. Eigentlich sollte man hier keine Werte vorgeben, wenn man es aber macht, warum auch immer, könnte es zur Verwirrung führen, wenn der vorgegebene Wert ignoriert wird.
|
AW: Int-Feld nachträglich auf autoincrement setzen
Och, da halte ich es wie Linus Torvalds:
Zitat:
|
AW: Int-Feld nachträglich auf autoincrement setzen
Zitat:
Die Problemtik wird richtig schön, wenn alte Datenbestände importiert werden müssen. Angenommen, ich muss Rechnungen importieren und die zugehörigen Artikel auch. Die IDs werden Lücken enthalten usw. Verwende ich da jetzt Generatoren / aktive Trigger (ohne die alten IDs anzugeben) dann zählen die einfach dumm hoch. Sieht ja nicht so schlimm aus. :P Bei den Rechnungen, sofern es da nur Positionen gibt, da könnte das noch gehen, aber wehe die Artikel erhalten neue IDs. Dann haben die Rechnungspositionen nicht vorhanden /völlig falsche IDs. In solchen Fällen muss man die ursprünglichen IDs fast überall verwenden. Also Trigger deaktivieren. Ist erst mal alles importiert, dann sollte man auch den Trigger aktivieren, auf grössten bereits vorhandene ID + 1 setzen. Das wurde hier zwar in Halbsätzen irgendwie angesprochen, aber nicht so richtig. :mrgreen: |
AW: Int-Feld nachträglich auf autoincrement setzen
Zitat:
Ich verfahre auch gelegentlich wie DeddyH es beschrieben hat. Das geht aber nur, wenn ich technische Interna der Implementierung kenne und gezielt ID unterhalb des Generators bzw sogar unter dessen initalem Startwert nehme. Ansonsten sehe ich das so wie mkinzler, die Anwendung sollte sich für den Anwender transparent verhalten. |
AW: Int-Feld nachträglich auf autoincrement setzen
Zitat:
Was soll sich Otto-Normaluser unter einem "technischen und einem fachlichen Schlüssel" vorstellen? :shock: Oder was ist das ? "die Anwendung sollte sich für den Anwender transparent verhalten". Das sind lediglich Schlagwörter, die einem vorgaukeln, einer wisse schon was er sagt. Ich übersetze das mal so : zu jedem Datensatz gehört eine ID (könnte man "technischer Schlüssel" nennen), die der Endbenutzer allerdings weder sehen noch manipulieren soll (Transparenz ?). Im Programm selbst wird nur mit merkbaren Nummern hantiert (fachliche Schlüssel ?). Sprich : Artikel-Nr., Rechn.-Nr. usw. Man nimmt nun eine Art.-Nr. aber nicht, um sie in sämtlichen abhängigen Tabellen, z.B. Rechnungspositionen zu verwenden. Denn was passiert mit den Rechnungen, sofern sich eine Art.-Nr. ändert ? Richtig. Im Falle, dass sich eine Art.-Nr. ändert müssen alle Rechnungspositionen angepasst werden (im Normalfall noch viel mehr). Also entkoppelt man die vermeintlich wichtige Art.Nr. vom Rest und behandelt sie als normales Feld (wie z.B. Preis, Artikel-Bez.). Macht man das so, dann braucht man aber trotzdem noch eine eindeutige Identifikationsnr. für einen Datensatz, also eine ID. Denn die ist auch dann eindeutig, wenn sich das Feld "Art.-Nr." ändert. Jetzt wären wir beim Fall "Int-Feld nachträglich auf autoincrement setzen". Sofern das um eine ID geht, dann nützen Generatoren/Trigger zuerst mal gar nichts. Denn die ID ist ja schon vorhanden. Wie bei meinem Beispiel Importieren von Fremddaten. Der ID-Wert muss dann auf einen vernünftigen Anfangswert gesetzt werden. Erst dann kann der Trigger ohne Kollisionen aktiv werden. So etwas hilft da auch nur halb :
Delphi-Quellcode:
Da wird die ID zwar nur hochgezählt, wenn die ID noch nicht bekannt ist, aber was, wenn die neu erzeugte per Insert in die Tabelle eingefügt werden soll, aber bereits da ist ? :shock:
set term ^;
CREATE TRIGGER Table1_BI FOR T1 ACTIVE BEFORE INSERT POSITION 0 AS BEGIN if (NEW.ID is NULL) then NEW.ID = GEN_ID(GEN_Table1_ID, 1); END!! set term ;^ |
AW: Int-Feld nachträglich auf autoincrement setzen
Zitat:
Zitat:
Im dargestellten Fall wäre es intransparent, wenn der Anwender eine ID vergeben kann, die manchmal 1:1 übernommen wird, manchmal aber nicht (abhängig von der Triggerlogik) Zitat:
Zitat:
Zitat:
Zitat:
Verwendet eine Applikation den via Trigger erzeugten Primärschlüssel (von mir zuvor technischer Schlüssel genannt) zur Darstellung von fachlichen Inhalten (z.B. die Rechnungsnummer), dann ist das ganze natürlich für die Tonne. Genau diesem Problem galt mein Hinweis, diese Schlüssel besser von vornherein getrennt zu verwalten. Zitat:
|
AW: Int-Feld nachträglich auf autoincrement setzen
Zitat:
a) alle (primärschlüssel) werden per Trigger/Sequence/autoincrement erzeugt. b) für neue Datensätze wird eine automatische Schlüsselerzeugung genutzt, deren Minimalwert einen hinreichenden Abstand zu den existierenden Altschlüsseln hat. c) Du läßt die Schlüssel durch ein schwarzes Loch erzeugen, darfst aber nicht vergessen, die Tageshöchsttemperatur der letzten 743 Tage von Helsinki mit in die Berechnung aufzunehmen. Solltest Du allerdings den Kölner Pegel der Jahre 1850-1865 nutzen mußt Du naturlich die Sonnenscheindauer der ersten drei Maitage in Berlin im Jahre 1756 mit einbringen. Gruß K-H |
AW: Int-Feld nachträglich auf autoincrement setzen
Ihr seid theoretische Möchtegern-Schlaumeier. :mrgreen:
Also gut, nehmen wir leere Datenbank. Mit IDs, Triggern usw. Ohne Eingriffe sitzt Generator erst mal auf 1. Zitat:
Dann noch 3 neue Artikel, damit sind ID 4,5,6 weg. So weit so gut. Verdammt, die Rechnungspositionen müssen ja auch noch rein. Dabei gilt ja angeblich das hier : Zitat:
Sieht gut aus, aber die gesamte DB ist im Eimer ! :glaskugel: So und jetzt reichts. Wer den offensichtlichen Fehler nicht sieht, der muss sich mal mit DB-Grundlagen befassen. |
AW: Int-Feld nachträglich auf autoincrement setzen
Und deshalb sind (bei mir) alle PK künstliche Schlüssel, die per Trigger/Generator befüllt werden. ArtNr wäre dann frei zu vergeben, aber unique. Wenn man will/muss, kann man also die Originalnummer behalten, solange sie eindeutig ist. Aber da sie ja vorher PK war, sollte das in jedem Fall zutreffen.
|
AW: Int-Feld nachträglich auf autoincrement setzen
Zitat:
(ich hab im Augenblick das Vergnügen eine DB wieder so hinzubiegen, das die Schlüssel wieder passen, darum bin ich ein wenig gereizt) Gruß K-H |
AW: Int-Feld nachträglich auf autoincrement setzen
Zitat:
Zitat:
|
AW: Int-Feld nachträglich auf autoincrement setzen
Zitat:
Was nützt eine saubere Trennung von technischen und fachlichen Schlüsseln im einen Objekt, wenn ich sie in abhängigen Objekten nicht fortführe? |
AW: Int-Feld nachträglich auf autoincrement setzen
Was heisst auf halbem Weg ? Was soll sauber getrennt werden ? Es muss sauber unterschieden werden zwischen IDs, sonstigen Datensatz-Feldern und dem Datensatz an sich. Vor allem gilt aber folgendes : Einmal ID immer ID ! Die soll, besser gesagt DARF nicht geändert werden. Insbesondere nicht durch falsche Generatoren oder Trigger, bzw. durch falsches Verständnis, wie die ID vergeben wird und was dahintersteckt.
|
AW: Int-Feld nachträglich auf autoincrement setzen
Zitat:
Das Importproblem, das Du hier darstellst, ist doch nur Resultat eines mangelhaften Datenmodells. |
AW: Int-Feld nachträglich auf autoincrement setzen
Zitat:
"Int-Feld nachträglich auf autoincrement setzen" Zitat:
|
AW: Int-Feld nachträglich auf autoincrement setzen
Zitat:
Bevor du dich in diesen Thread eingeschalten hast, wurde hier sachlich diskutiert und mögliche Probleme, die hierbei bestehen können angesprochen. Man kann auch diskutieren ohne andere dabvei zu beleidigen und sich selber zu beweihräuchern! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:55 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz