![]() |
AW: Unique bei 4 verschiedenen Feldern
Danke Danke,
werde ich morgen mal versuchen umzusetzen :thumb: |
AW: Unique bei 4 verschiedenen Feldern
Ich möchte mich noch mal bei allen bedanken,:-D
ich dachte schon das bekommst Du leider nicht hin und dann habe ich es mal mit "=" probiert und es klappte wunderbar. bei "<>" oder "not in" hat SQL Firebird, dass nur in der gleichen Zeile richtig angemeckert, warum ? Keine Ahnung !
SQL-Code:
/* Check constraints definition */ ALTER TABLE "FolderDsg" ADD CONSTRAINT CHK2_FOLDERDSG CHECK (ORDER1 = ORDER3); ALTER TABLE "FolderDsg" ADD CONSTRAINT CHK3_FOLDERDSG CHECK (ORDER1 = ORDER4); ALTER TABLE "FolderDsg" ADD CONSTRAINT CHK4_FOLDERDSG CHECK (ORDER2 = ORDER3); ALTER TABLE "FolderDsg" ADD CONSTRAINT CHK5_FOLDERDSG CHECK (ORDER2 = ORDER4); ALTER TABLE "FolderDsg" ADD CONSTRAINT CHK6_FOLDERDSG CHECK (ORDER3 = ORDER4); ALTER TABLE "FolderDsg" ADD CONSTRAINT CHK1_FOLDERDSG CHECK (ORDER1 = ORDER2); /******************************************************************************/ /* Unique Constraints */ /******************************************************************************/ ALTER TABLE "FolderDsg" ADD CONSTRAINT UNQ1_FOLDERDSG UNIQUE (ORDER1) USING INDEX "_IDXORDER1"; ALTER TABLE "FolderDsg" ADD CONSTRAINT UNQ2_FOLDERDSG UNIQUE (ORDER2) USING INDEX "_IDXORDER2"; ALTER TABLE "FolderDsg" ADD CONSTRAINT UNQ3_FOLDERDSG UNIQUE (ORDER3) USING INDEX "_IDXORDER3"; ALTER TABLE "FolderDsg" ADD CONSTRAINT UNQ4_FOLDERDSG UNIQUE (ORDER4) USING INDEX "_IDXORDER4"; |
AW: Unique bei 4 verschiedenen Feldern
Sicher daß es nicht
Delphi-Quellcode:
anstatt
!=
Delphi-Quellcode:
heißt?
<>
Vieleicht geht auch nur
Delphi-Quellcode:
NOT (X IN [...])
Kenn mich mit der Syntax vom FB nicht so aus, aber da gibt es ja die komischsten Dinge. Und wenn die Felder auch noch die NULL enthalten können, dann muß man eventuell aufpassen, wie die Vergleichsoperatoren darauf reagieren. Zitat:
SQL-Code:
Gut, bei deiner Variante bekommt man wenigstens noch an Hand des Constraint-Namens mit, welche Felder da in Konflikt stehen.
ALTER TABLE "FolderDsg" ADD CONSTRAINT CHK_FOLDERDSG CHECK ((ORDER1 = ORDER2) AND (ORDER1 = ORDER3)
AND (ORDER1 = ORDER4) AND (ORDER2 = ORDER3) AND (ORDER2 = ORDER4) AND (ORDER3 = ORDER4)); |
AW: Unique bei 4 verschiedenen Feldern
:oops:Ganz so einfach ist es wohl doch nicht !
Ich habe die Datenbank neu aufgesetzt und nun geht das leider nicht mehr wie erhofft. Da muss ein Trigger im Spiel gewesen sein den ich mit Zufall ausgelöst hatte. Werde berichten wenn ich das gelöst habe |
AW: Unique bei 4 verschiedenen Feldern
Hallo
Danke noch mal für die Hilfen, Nachdem ich mich ein wenig mit SQL beschäftigt habe, möchte ich meine Lösung präsentieren. Ich habe einfach eine neue Tabelle Dummy erstellt und schreibe da einfach alle Werte in DUMMYCOUNTER hinein. Das Feld ist auch Unique und meckert wenn was 2 mal versucht wird einzugeben. Falls mal ein Datensatz gelöscht werden soll, wird dieser auch in DUMMYCOUNTER gelöscht. Vielleicht weiss ja jemand eine Verinfachung des ganzen ?
SQL-Code:
******************************************************************************/
/* Unique Constraints */ /******************************************************************************/ ALTER TABLE "FolderDsg" ADD CONSTRAINT UNQ1_FOLDERDSG UNIQUE (ORDER1) USING INDEX "_IDXORDER1"; ALTER TABLE "FolderDsg" ADD CONSTRAINT UNQ2_FOLDERDSG UNIQUE (ORDER2) USING INDEX "_IDXORDER2"; ALTER TABLE "FolderDsg" ADD CONSTRAINT UNQ3_FOLDERDSG UNIQUE (ORDER3) USING INDEX "_IDXORDER3"; ALTER TABLE "FolderDsg" ADD CONSTRAINT UNQ4_FOLDERDSG UNIQUE (ORDER4) USING INDEX "_IDXORDER4"; CREATE UNIQUE INDEX "FolderDsg_IDX1" ON "FolderDsg" (ORDER1, ORDER2, ORDER3, ORDER4); /******************************************************************************/ /* Triggers */ /******************************************************************************/ /* Trigger: FOLDERDSG_DELETE */ CREATE OR ALTER TRIGGER FOLDERDSG_DELETE FOR "FolderDsg" ACTIVE BEFORE DELETE POSITION 1 AS declare variable theorder1 bigint; begin if (OLD.order1 is not null) then begin theorder1 = OLD.order1; DELETE FROM DUMMY WHERE DUMMYCOUNTER = :theorder1; end if (OLD.order2 is not null) then begin theorder1 = OLD.order2; DELETE FROM DUMMY WHERE DUMMYCOUNTER = :theorder1; end if (OLD.order3 is not null) then begin theorder1 = OLD.order3; DELETE FROM DUMMY WHERE DUMMYCOUNTER = :theorder1; end if (OLD.order4 is not null) then begin theorder1 = OLD.order4; DELETE FROM DUMMY WHERE DUMMYCOUNTER = :theorder1; end end ^ /* Trigger: FOLDERDSG_UPDATE */ CREATE OR ALTER TRIGGER FOLDERDSG_UPDATE FOR "FolderDsg" ACTIVE AFTER UPDATE POSITION 0 AS declare variable theorder1 bigint; declare variable theorder2 bigint; begin if (OLD.order1 is not null) then begin theorder1 = NEW.order1; theorder2 = OLD.order1; update DUMMY set DUMMYCOUNTER = :theorder1 WHERE DUMMYCOUNTER = :theorder2; end -- that works well ---- if ((OLD.order1 is null) and NEW.order1 is not null ) then begin INSERT INTO DUMMY (DUMMYCOUNTER) values (NEW.order1); end ----------------------------------------- if (OLD.order2 is not null) then begin theorder1 = NEW.order2; theorder2 = OLD.order2; update DUMMY set DUMMYCOUNTER = :theorder1 WHERE DUMMYCOUNTER = :theorder2; end -- that works well ---- if ((OLD.order2 is null) and NEW.order2 is not null ) then begin INSERT INTO DUMMY (DUMMYCOUNTER) values (NEW.order2); end ----------------------------------------- if (OLD.order3 is not null) then begin theorder1 = NEW.order3; theorder2 = OLD.order3; update DUMMY set DUMMYCOUNTER = :theorder1 WHERE DUMMYCOUNTER = :theorder2; end -- that works well ---- if ((OLD.order3 is null) and NEW.order3 is not null ) then begin INSERT INTO DUMMY (DUMMYCOUNTER) values (NEW.order3); end ----------------------------------------- if (OLD.order4 is not null) then begin theorder1 = NEW.order4; theorder2 = OLD.order4; update DUMMY set DUMMYCOUNTER = :theorder1 WHERE DUMMYCOUNTER = :theorder2; end -- that works well ---- if ((OLD.order4 is null) and NEW.order4 is not null ) then begin INSERT INTO DUMMY (DUMMYCOUNTER) values (NEW.order4); end ----------------------------------------- end ^ |
AW: Unique bei 4 verschiedenen Feldern
Sehe ich das richtig, dass alle 4 Spalten einzeln und in Kombination eindeutig sein sollen? Und dann noch zusätzlich über alle 4 Spalten?
|
AW: Unique bei 4 verschiedenen Feldern
Zitat:
zum Code: Ist es unter Firebird notwendig die Werte erst in Variablen zu schreiben? Sonst kann man direkt new/old Werte in die Statements setzen. Das Update find ich etwas übertrieben. Entweder es gibt einen Wert, dann Insert oder es wird einer entfernt, dann delete. Nun nochmal meine Eingangsbemerkung: Das Konstrukt ist ziemlich daneben. Der Clou aber ist nun: Die von Dir entworfene Hilfskonstruktion ist ziemlich nahe an dem, wie es normalerweise umgesetzt würde (mit dem Vorteil, das man ohne Modelländerung beliebig viele Werte verwalten kann statt maximal 4) Diese denormalisierten Felder laufen natürlich auch an jeder anderen Stelle, wo sie verwendet werden, gegen die relationalen Prinzipien und verursachen Extra (Code) Aufwand. Falls Du das grad erfunden hast, wirf es wieder weg. Falls es sich um ein bestehendes System handelt, versuch lieber, es abzuschaffen. Das eigenartige bei solchen Lösungen ist ja meist, dass irgendwer meint, auf diese Weise etwas Aufwand zu sparen. "Nein, dafür machen wir nicht extra ne neue Tabelle!" |
AW: Unique bei 4 verschiedenen Feldern
jobo ich bin Hobby Programmierer. Das funktioniert gut ist es.
Wenn Du eine bessere Lösung weißt nur zu. Ich habe ein CASE bei ![]() aufgemacht und da hat mir jemand dazu geraten. Das Problem ist das Firebird nur die Uniques in der gleichen Spalte oder Zeile anmeckert. Ich habe etwas mehr über Datenbanken gelern und das freut mich sehr. Danke für eure Hilfen. |
AW: Unique bei 4 verschiedenen Feldern
Zitat:
Viele der Kommentare bei SO sind aber die selben wie der von Jobo und anderen hier: Du hast zwar eine Lösung für dein Problem gefunden, aber du hättest erst gar nicht das Problem, wenn du deine Tabellenstruktur evtl. anders designed hättest. Darauf wollten die vielen dezenten Hinweise glaub ich hinaus. Da aber nie gesagt wurde, wofür das eigentlich gedacht ist, konnte man nicht konkreter sagen, was man hätte anders/besser machen können, daher immer nur Sätze ala: "Überdenk mal deine Datenstruktur", die nicht böse gemeint waren (so wie ich die lese) sondern als guter Rat gedacht. Beispiel zu einer Lösung, die deiner ähnelt, einer Normalisierung aber näher kommt könnte sein, deine Dummy-Tabelle so zu gestellten, dass sie drei Spalten hat. Spalte 1 eine ID mit der du sie mit der Haupttabelle verknüpfst. Spalte 2 für die Werte 1-4 die deinen vier Feldern aus der Haupttabelle entsprechen und Spalte drei in der diese "einmaligen" Zahlen kommen sollen. Schlüssel ist dann Spalte 1. Unique muss die Kombination aus 1 und 2 sein, und Unique muss der Wert in Spalte 3 sein. Sieht vllt. zunächst nach mehr Arbeit aus, als deine Version, aber man muss weniger programmieren, kann mehr der DB überlassen, und kann's leicht erweitern auf 5 oder 6 Felder in denen die Zahlen eindeutig sein müssen. Und man sieht in der Dummy-Tabelle, wozu dortige Einträge gehören. |
AW: Unique bei 4 verschiedenen Feldern
Wahrscheinlich habe ich da etwas falsch verstanden, aber wenn die (Schlüssel) in allen 4 Spalten unique sin sollen, warum werden sie nicht von einem Generator erzeugt und gut ist?
Gruß K-H |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:22 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-2025 by Thomas Breitkreuz