Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Feld darf nur einmal vorkommen (https://www.delphipraxis.net/18762-feld-darf-nur-einmal-vorkommen.html)

Hansa 24. Mär 2004 13:11


Feld darf nur einmal vorkommen
 
Hi,

in mehreren Tabellen brauche ich Felder, die nur einmal vorkommen dürfen. Entsetzt mußte ich jetzt feststellen, daß das gar nicht so einfach geht und es noch gar nicht in der Datenbank realisiert ist. Muß ich da einen Index verwenden oder wie oder was ? Es geht um Interbase.

Tyrael Y. 24. Mär 2004 13:13

Re: Feld darf nur einmal vorkommen
 
ich kenn Interbase nicht, aber gibst es da kein Primary Key ?

Steffen 24. Mär 2004 13:13

Re: Feld darf nur einmal vorkommen
 
Hallo Hansa!

Zitat:

in mehreren Tabellen brauche ich Felder, die nur einmal vorkommen dürfen.
Wie soll man das verstehen?
Kannst Du dein Problem etwas konkreter beschreiben?

Gruß,
Steffen

Hansa 24. Mär 2004 13:20

Re: Feld darf nur einmal vorkommen
 
Der Primary Key ist die ID. Eine Kundennummer z.B. darf aber auch nur einmal vorkommen. Diese Arbeit will ich der Datenbank überlassen.

Steffen 24. Mär 2004 13:24

Re: Feld darf nur einmal vorkommen
 
Das macht eigentlich keinen Sinn, dann kannst/solltest Du gleich die Kundennummer als Primary-Key wählen und die Id weglassen!
Wenn unbedingt sein muss gibt's ja auch noch Secondary-Key's...

Gruß,
Steffen

DelphiDeveloper 24. Mär 2004 13:26

Re: Feld darf nur einmal vorkommen
 
hi hansa,
wie siehts denn aus mit dem Feld als Unique?

Robert_G 24. Mär 2004 13:28

Re: Feld darf nur einmal vorkommen
 
Secondary Keys???

Hansa, lege doch einfach ein unique constraint auf die Spalte. Wenn die Kunden nr. nicht nurmerisch ist würde ich sie auch nicht als prim. Key ablegen.
Deine Überlegung war also schon richtig.

Steffen 24. Mär 2004 13:32

Re: Feld darf nur einmal vorkommen
 
Wenn die Kundennummer Alphanumerisch ist, ist ein Key wirklich nciht das richtige... Hatte ich nicht mit in Betracht gezogen.

Hansa 24. Mär 2004 13:37

Re: Feld darf nur einmal vorkommen
 
Zitat:

Zitat von DelphiDeveloper
hi hansa,
wie siehts denn aus mit dem Feld als Unique?

Ja, genau so wollte ich das machen, finde aber nicht wo. So in Richtung NULL <--> NOT NULL. Vielleicht bin ich heute auch nur blind. 8) Gelle Robert. :zwinker:

P.S.: was hat das mit alphanumerisch zu tun ?

DelphiDeveloper 24. Mär 2004 13:41

Re: Feld darf nur einmal vorkommen
 
ibexpert/
Tabelle aufmachen
tabsheet Beschränkungen
tabsheet Uniques

die felder muessen als not null deklariert sein

Hansa 24. Mär 2004 13:55

Re: Feld darf nur einmal vorkommen
 
Ja, bin doch blind. 8) Aber es gibt noch ein Problem: trotz leerer Tabelle kommt diese Fehlermeldung :
Zitat:

Zitat von IBExpert
Invalid insert or update value(s): object columns are
constrained - no 2 table rows can have duplicate column values.
attempt to store duplicate value (visible to active transactions) in unique index "RDB$48".

Wenn ich nur die Nr. nehme. Packe ich die ID noch dabei, dann geht es auch. Wo finde ich jetzt, was RDB$48 genau ist ?

DelphiDeveloper 24. Mär 2004 14:03

Re: Feld darf nur einmal vorkommen
 
das ist der interne RDB$Indexname

findest du in Tabelle RDB$Indices

Robert_G 24. Mär 2004 14:16

Re: Feld darf nur einmal vorkommen
 
Schreibe mal ein INSERT per Hand.
Ich denke mal du kannst die Werte mit einem anderen Programm noch nicht sehen, weil die Transaktion nnoch nicht abgeschlossen ist. Es ist aber möglich, dass in deiner Anwendung 2 INSERTs abgesetzt worden.
Wenn dein INSERT "zu Fuss" klappt, dann hast du einen Fehler in der Anwendung (du schreibst 2-mal).

Hansa 24. Mär 2004 14:25

Re: Feld darf nur einmal vorkommen
 
select * from RDB$INDICES

Dann werden die RDB$RELATION-NAMES aufgeführt unter anderem auch RDB$INDICES. Aber nichts zu sehen von RDB$48

Leuselator 24. Mär 2004 15:59

Re: Feld darf nur einmal vorkommen
 
Moin Hansa,

ZU: "was hat das mit mit alphanumerisch zu tun?"
Alphafelder als primary verlangsamen den Zugriff und machen Dir das Leben im Programm schwerer - prinzipiell geht es schon, aber wer nimmt schon die Säge, um einen Nagel in die Wand zu schlagen? :mrgreen:

ZU: "Uniqueproblem"
Wenn Du etwa alt-Datensätze nicht löschst, sondern nur deaktivierst und beim Update statt Update tatsächlich den Altsatz deaktivierst und einen neuen einfügst (um z.B. die Tabelle zu historisieren, also alle Änderungen im Nachhinein nachvollziehbar zu machen), fällst Du natürlich mit dem Unique-Index in der Tabelle auf die Nase, da die Kd-Nummer im Altsatz schon drinn ist, kann der Neusatz nicht eingefügt werden. Wenn das Problem aus der Ecke daherkommt, dann lager die KdNummer in eine Lookuptabelle aus (Fields: (Id Int) und (KdNummer alpha unique)) und speicher in der eigentlichen nur die Id der Kundennummer - dann bist Du das Problem los.

Hoffe das hüleft
Gruß

Hansa 24. Mär 2004 18:04

Re: Feld darf nur einmal vorkommen
 
Zitat:

Zitat von Leuselator
...aber wer nimmt schon die Säge, um einen Nagel in die Wand zu schlagen?

Das geht schon ! z.B. mit der "Rückseite" einer Metallsäge. :lol:

Jetzt wirfst Du allerdings einen völlig neuen Aspekt auf, mit der Historie etc. Mit dem zusammengesetzten key wäre das tatsächlich relativ einfach zu machen. Im Moment aber egal.

Ihr macht es aber jetzt immer noch zu kompliziert. Die ID ist der primary key. Die Nr. ist ein integer. Da ich bisher aber keinerlei Performance-Probleme festgestellt habe, sind die Indices vorerst auch mal noch außer Acht gelassen. Die Test-DB hat allerdings nur ca. 30 MB und ist lokal.

Aus Versehen habe ich nun einen Kunden mit derselben Nr. eines bestehenden angelegt. Und das muß ich eben abfangen. Sonst nichts.

Robert_G 24. Mär 2004 18:06

Re: Feld darf nur einmal vorkommen
 
Wenn die Kunden Nr. numerisch ist, dann schmeiß' die ID weg und mache die Kunden Nr. zum prim. Key.
Färtisch!

Hansa 24. Mär 2004 18:32

Re: Feld darf nur einmal vorkommen
 
1. Was habt ihr nur mit dem numerisch/alphanummerisch ? Inwiefern spielt das eine Rolle ?

2. wie wirkt sich aus, welches Feld den Primary Key hat ?

3. Das hier funktioniert :

ALTER TABLE KG ADD CONSTRAINT NQ_KG UNIQUE (NR);
ALTER TABLE KG ADD PRIMARY KEY (ID);

Wenn ich den primary key von ID auf NR lege und den UNIQUE entferne, was ist dann (siehe auch 2) ?

Bei der Kundentable kommt aber eine Fehlermeldung (siehe weiter oben).

Delphi_Fanatic 25. Mär 2004 13:30

Re: Feld darf nur einmal vorkommen
 
Wieso machst Du es nicht einfach so, dass Du in Deinem BeforPost Event mit der SQL-Funktion (Max) den
höchsten Wert Deiner Primary-Key-Spalte ermittelst, einen drauf addierst, und dann den Wert als neuen
Primary-Key abspeicherst ?

So kannst Du Dir doch auf recht simple Weise einen eindeutigen Primary-Key selbst erzeugen.

Wenn Du Dir von der Datenbank irgendwelche Primary-Keys erstellen lässt (wie z.B. mit diesem
Typ 'AutoWert' bei MSAccess), dann bist Du mit Deiner Anwendung auch fest an diese Datenbank
gebunden und kannst nicht so einfach irgendwann mal auf eine andere Datenbank umsteigen.

Wenn Du Dir dagegen selber den Primary-Key erstellst, dann könntest Du Deine Anwendung recht leicht
von der Benutzung einer DB (wie z.B. Access) auf eine andere DB (wie z.B. SQL-Server oder meinetwegen
IB) 'umschalten'.

P.S. und natürlich müßtest Du vor diese Sache mit der Primär-Key-Erstellung eine if-Abfrage setzten,
mit der Du sicherstellts, dass der Primär-Key auch nur dann erstellt wird, wenn er noch nicht vorhanden
ist . (also nur nach einem Insert, und nicht nach jedem Edit => Post).

Robert_G 25. Mär 2004 13:47

Re: Feld darf nur einmal vorkommen
 
Das ist doch sinnlos.
Erstens hat es Hansa mit einer DB zu tun (er hat kein Access und Co.), deshalb kann er einen neuen Datensatz an den Server schicken und der generiert innerhalb der DB einen neuen Schlüssel.
Dieses Abfragen, hochzählen und dann erst Abschicken widerspricht doch komplett dem Konzept von stored procedures!

Hansa 25. Mär 2004 16:35

Re: Feld darf nur einmal vorkommen
 
Ähh, hmmm, :shock:

also mit access und co. will ich nix zu tun haben. Ich muß kein Telefonverzeichnis proggen, sondern eine relationale DB, ungefähr 50-100 Tables). Und das hängt alles miteinander zusammen. Die DB soll auch auf einem Linux-Server liegen können. und und ...

Die Frage läuft im Moment darauf hinaus, wo hin der Primary Key soll.

Sharky 25. Mär 2004 16:46

Re: Feld darf nur einmal vorkommen
 
Zitat:

Zitat von Hansa
...also mit access und co. will ich nix zu tun haben.

Das sagt ja auch keiner.

Zitat:

Zitat von Hansa
... Ich muß kein Telefonverzeichnis proggen, sondern eine relationale DB,

Ich glaube kaum das DU ein Datenbanksystem programmiers ;-)

Zitat:

Zitat von Hansa
...Die DB soll auch auf einem Linux-Server liegen können. und und....

Wo die liegt ist doch nicht wichtig.

Und und und..... Was soll jemand damit anfangen?
Akzeptiere doch einfach mal das Du einen grundsätzlichen Fehler in der Planung deiner DB hast.
Danach kannst Du so tun als würdest Du wissen um was es geht.

Sorry für meine harten Worte. Aber in der letzen Zeit lese ich von Dir immer mehr Beiträge in der obigen Art.

Hansa 25. Mär 2004 17:19

Re: Feld darf nur einmal vorkommen
 
Zitat:

Ich glaube kaum das DU ein Datenbanksystem programmiers ;-)

Wo die liegt ist doch nicht wichtig.

Und und und..... Was soll jemand damit anfangen?
Akzeptiere doch einfach mal das Du einen grundsätzlichen Fehler in der Planung deiner DB hast.
Danach kannst Du so tun als würdest Du wissen um was es geht.

Sorry für meine harten Worte. Aber in der letzen Zeit lese ich von Dir immer mehr Beiträge in der obigen Art.
Wenn Du meinst. 8) Antwort kam bislang jedenfalls keine. Na gut, dann frage ich eben erst gar nicht mehr weiter. :stupid:

Leuselator 25. Mär 2004 20:41

Re: Feld darf nur einmal vorkommen
 
Hey Hansa alter Junge nicht gleich einschnappen, wenn der Hai mal zuschnappt! :-)

Allerdings ist etwas daran: Du mußt 'ne Entscheidung treffen:
1. Du schränkst die möglichen Zieldatenbanken auf ausgewachsene DB's (also solche mit StoredProcedures, Trigger, Constraints etc.) ein (btw. gibt es DB2 von IBM, welches durchaus ein ausgewachsenes DBMS ist auch für Linux) und verkleinerst dadurch Deinen möglichen Markt, kannst aber andererseits auch systematisch vernünftige Ansätze verwirklichen.
Oder
2. Du verzichtest auf die Weitergehenden Möglichkeiten ausgewachsener DBMS's, vergößerst Deinen Markt und "frickelst" es irgendwie zurecht.

Es gibt immer Argumente für die eine und die Andere Seite - soll hier nicht das Thema sein.

Richtig ist es auf jeden Fall, die Business-Logik strikt von der DatenbankStruktur- und Integrität zu trennen: Morgen schießt Deinem Kunden ein Furz aus dem Darm mit dem Umweg über's Rückenmark ins Hirn und Du wirst beauftragt, die Kundennummern um den Tag des Geburtsdatums zu erweitern - was dann (kein Scherz - habe solche und noch viel krudere Nummern erlebt)? Dann hängt Deine Datenbank womöglich komplett an den alten Kundennummern, da Du diese als Primary verwendet hast - viel Spaß damit!

Deshalb denk doch nochmal ernsthaft über eine Auslagerung der Kundennummer in eine separate Lookuptabelle nach, und benutze ansonsten konsequent servergenerierte ID's als Primary Keys in Deinen Tabellen. Wenn dann eine Änderung der Businesslogik in Bezug auf die Kundennummern stattfindet, kannst Du die ohne Kummer in Deiner DB nachvollziehen.

In meinem aktuellen Projekt habe ich eine DB mit ca. 160 Tabellen und insgesamt etwa 30 Mio Datensätzen. All diese Tabellen referenzieren am Ende mehr oder weniger direkt eine zentrale Entitätstabelle, die aus 6 Spalten besteht: Id,Typ,DatumStart,DatumStop,IdErzeuger,IdLöscher. Egal, wie sich die Hülle (Atribute) der Entitäten in Zukunft ändert - ich werde immer wieder einen EinEinDeutigen Zugriff auf die Entität haben - eine wirkliche Beruhigung!

Also schnapp wieder aus, und benutze den Hammer zum nageln und die Säge zum sägen :-)
(Ich arbeite schließlich auch ab jetzt mit der Objektablage!)

Gruß

PS: die Protagonisten der "Select max(Id)"-Methode sollten sich mal fragen, wie sicher diese Variante im Mehrbenutzerbetrieb ist, wenn 2 Leute gleichzeitig einen neuen Kunden anlegen wollen, aber leicht zeitlich versetzt posten. Die Katastrophe ist dann vorprogrammiert. Solche sachen gehören nunmal in die Kompetenz der DB und nicht in die der Clients.

kiar 25. Mär 2004 22:25

Re: Feld darf nur einmal vorkommen
 
Dem ist nicht's hinzu zufügen :thuimb:

ein schlechtes DB Design wird sich später immer rächen.

raik

@Hansa, denke an das Tut mit der Objektanlage, wenn du mal wieder hier bist :mrgreen:

Hansa 28. Mär 2004 16:15

Re: Feld darf nur einmal vorkommen
 
Habe mich jetzt strikt an die Theorie gehalten. DIe IDs erhalten bzw. behalten den Primary Key. Siehe Leuselators Post. Den PK lege ich nicht auf eine Nr., wie Robert_G vorgeschlagen hat. Ansonsten habe ich die uniques so gemacht wie von DelphiDeveloper vorgeschlagen.

Der Haken an der Sache war lediglich ein nicht vorhandenes Feature in IBExpert. Normalerweise werden die Identifier automatisch vergeben. Manchmal aber auch doppelt. Das fiel mir anfangs nicht auf.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:05 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