Neuigkeiten:

Wenn ihr euch für eine gute Antwort bedanken möchtet, im entsprechenden Posting einfach den Knopf "sag Danke" drücken!

Mobiles Hauptmenü

Foreign-Key auf mehrere Felder

Begonnen von dedidado, März 16, 2019, 13:15:31

⏪ vorheriges - nächstes ⏩

dedidado

Hallo zusammen,
hab folgendes Problem:
Ich muss zwischen zwei Tabellen eine Referentielle Integrität herstellen, aber über mehrere Spalten die nicht in einem Foreign-Key zusammenfassbar sind.
Beispiel: von Tabelle Kontakt(PK=ID) aus muss ich zwei Felder in der Leistungstabelle (KundenID und PersonalID) aktuell halten.
Einmal den Kunden und einmal den Mitarbeiter. Sobald ich aber einen zweiten Foreign-Key für die PersonalID erstellen will, natürlich ebenfalls mit Aktualisierungsweitergabe aber keine Löschweitergabe, erhalte ich folgende Meldung:

"Das Einführen der FOREIGN KEY-Einschränkung 'FK_Kontakt_Leistung2' für die 'Kontakt'-Tabelle kann Schleifen oder mehrere Kaskadepfade verursachen. Geben Sie ON DELETE NO ACTION oder ON UPDATE NO ACTION an, oder ändern Sie andere FOREIGN KEY-Einschränkungen.
Die Einschränkung konnte nicht erstellt werden."

Aber ohne Aktualisierungsweitergabe nützt mir das ganze nichts und andere Foreign-Keys kann ich auch nicht ändern, genausowenig wie das Datenmodell weiter zu normalisieren.

Aktuell hab ich nur den doch sehr aufwendigen und dazu, bzgl. des löschens, noch auf das Programm beschränkte Lösungsweg, nämlich ohne zweiten FK aber dafür mit Trigger für die Aktualisierung und im Programm verhindere ich dass der Quelldatensatz gelöscht werden kann, sofern noch abhängige Datensätze existieren. Aber auf Tabellenebene oder über Abfragen wird das Löschen dadurch nicht verhindert.

Hat jemand eine Idee oder gibt es eine andere Möglichkeit die ich noch nicht kenne, wie ich das auf dem SQL-Server selbst lösen kann?
oder wenigstens das Löschen schon auf dem SQL-Server verhindern kann?

Bin für jeden Tipp dankbar!
Dieter
  •  

MzKlMu

Hallo,
bitte zeige mal ein Bild des Beziehungsfensters, damit man eine Vorstellung hat von den Zusammenhängen.

Und an der Notwendigkeit der Aktualisierungsweitergabe bestehen auch Zweifel.
Schlüsselfelder müssen doch nicht geändert werden.
Gruß
Klaus
  •  

dedidado

die Beziehung zwischen den Tabellen ist ganz einfach:
Tabelle Kontakt mit ID als PK (ID ist keine Nr) ist verknüpft mit den Feldern KundenID und PersonalID in der Tabelle Leistung. Das ganze soll mit Aktualisierungsweitergabe aber nicht mit Löschweitergabe realisiert werden. In Access und vielen anderen Datenbanken, wie ich mehrfach gelesen habe, offenbar kein Problem.
Aber leider mit dem SQL-Server nicht  :(

Es soll auch nicht die ID der Kontakttabelle aktualisiert werden, wenn ich deinen letzten Satz richtig verstanden habe, sondern wenn die ID der Kontakttabelle geändert wird, sollen die Felder KundenID und PersonalID in der Tabelle Leistung aktualisiert werden.
  •  

MzKlMu

Hallo,
Du machst hier einen Denkfehler. Eine Aktualisierungsweitergabe ist doch im Regelfall gar nicht notwendig, wozu auch, die Schlüsselfelder sollten sich nie ändern.

Und wieso ist der Kontakt mit 2 Feldern verknüpft ?
Der Konakt gehört doch zum Kunden und wenn dann in der Leistung nur der Kontakt steht, hast Du doch automatisch auch den Kunden.

Mit Deiner verbalen Beschreibung kann ich nichts anfangen.
Es kann doch kein Problem sein, hier mal ein Beziehungsbild zu posten.
Gruß
Klaus
  •  

dedidado

Hallo Klaus,
Danke für deine Mühe, ein Problem ist es eigentlich nicht, wollte das Beispiel nur so einfach wie möglich halten.

Der Kontakt ist mit zwei Feldern verknüpft, weil bei der Leistung einmal der Kunde und einmal das Personal ausgewählt wird, beides aus der Kontakttabelle. Unterschieden wird das widerum über das Feld Typ in der Kontakttabelle, was aber für die Problemstellung hier keine Rolle spielt, deshalb hab ich das ganze auf die wenigen Felder beschränkt.

Die Aktualisierungsweitergabe ist aus dem Grund notwendig, da in der ID in der Kontakttabelle z.B. "MuellerHeidi" stehen kann und wenn sie heiratet, wird daraus "FischerHeidi" und damit würde der Bezug zur Leistung verloren gehen.
Es nützt auch nichts, über Sinn oder Unsinn des Istzustandes zu diskutieren. Das Datenmodell sieht so aus und ich muss hier eine Lösung finden. Natürlich hätte man daraus auch eine Zahl machen können, die sich nicht ändert, aber es ist leider nicht so.

Das zu ändern würde einer Neuprogrammierung gleich kommen. Denn es gibt noch weitere solcher Konstellationen. Die Kontakttabelle ist ihrerseits mit noch mehr als zwei Feldern aus einer anderen Quelltabelle verknüpft. Da gibt es Anrede, Titel, Konfession, Nationalität usw.... was alles in einer Tabelle steht, ebenfalls wieder durch Typ "unterteilt". Um allein das aufzulösen müsste ich ca. 40 neue Tabellen anlegen oder den PK in eine Zahl umwandeln.
Mit den Änderungen im Programm, egal wie, ein Fass ohne Boden...

Letztlich bleibt die eine Frage: gibt es eine SQL-Server basierte Lösung die verhindert dass der Quelldatensatz(Kontakt) gelöscht wird, sofern er noch in einer Leistung vorhanden ist ohne dass ein Foreign-Key existiert?
denn diesen muss ich leider für die zweite Beziehung löschen, da ansonsten die Aktualisierung via Trigger nicht greift. Eine Lösung für die Aktualisierung gibt es mit dem Trigger somit schon, nur leider funktioniert der Trigger nicht solange es den Foreign-Key gibt und wenn ich den FK lösche, ist nicht sichergestellt, dass der Quelldatensatz NICHT gelöscht werden kann.
  •  

MzKlMu

#5
Hallo,
Zitat"MuellerHeidi" stehen kann und wenn sie heiratet, wird daraus "FischerHeidi" und damit würde der Bezug zur Leistung verloren gehen.
Das ist das eigentliche Problem. In einer richtigen Datenbank ist das falsch.
Die MüllerHeidi sollte auf ewig immer den gleichen Primärschlüssel haben. Familienstandsänderungen sind in einer extra Tabelle zu erfassen mit einem Bezug zum PS des Kontakts. Da wurde von Anfang an der falsche Ansatz genommen.

Zum jetzigen Problem:
Wenn die Kontakttabelle 2x verknüpft werden muss, so ist die Kontakttabelle auch 2x in die Beziehungen aufzunehmen. Die 2 Tabelle wird von Access automatisch mit einem Aliasnamen (.._1) versehen.
Nur dann ist die Unterscheidung der der beiden Felder möglich. Und nur dann klappt auch die Aktualisierungsweitergabe.

Daher wollte ich ja unbedingt mal das Beziehungsbild sehen um zu sehen ob das auch so gemacht ist. Aber das scheint geheim zu sein. Normalerweise denke ich mir was dabei, wenn ich nach etwas frage.
Gruß
Klaus
  •  

dedidado

ja - du hast recht - optimal ist das nicht, aber falsch ist relativ, weil mit Access als DB funktioniert das schon seit Jahren ohne Probleme, so wie du es beschrieben hast.

Nur ich suche nicht nach einer Lösung mit Access - sondern nach einer mit dem SQL-Server!

Wie gesagt, Aktualisierungsweitergabe mit einem Trigger ist vorhanden und funktioniert, nur wollte ich sicherstellen, dass es nicht möglich ist, so unwahrscheinlich es auch sein mag, den Quelldatensatz zu löschen, nur weil ich die Beziehung nicht herstellen kann.
  •  

MzKlMu

Hallo,
und wie die Beziehungen jetzt genau angelegt sind, ist immer noch nicht klar.
Hast Du diese so angelegt wie oben beschrieben ?
Also die Kontakttabelle 2x aufgenommen.

Was kann denn blos so schwer sein, ein Beziehungsbild zu zeigen. Es genügt ja der entsprechende Ausschnitt.
Gruß
Klaus
  •  

dedidado

was ist denn daran nicht klar? der PK, bestehend aus einem Feld, geht von einer Tabelle zweimal auf jeweils ein anderes Feld einer anderen Tabelle, hab ich doch schon mehrfach geschrieben.

Sorry, ich versteh die ständige Nachfragerei nicht, es geht im wesentlichen um zwei Tabellen und insgesamt drei Feldern. Noch weniger ist ja kaum noch möglich! brauchts da wirklich ein Bild?

Mit dem SQL-Server ist nur eine Beziehung mit Aktualisierungweitergabe möglich, soviel weiß ich schon.
Deshalb die Frage, kennt jemand eine andere Lösung für die zweite Beziehung?
  •  

MzKlMu

Hallo,
Zitatgeht von einer Tabelle zweimal auf jeweils ein anderes Feld einer anderen Tabelle, hab ich doch schon mehrfach geschrieben.
Das ist aber falsch so, habe ich auch schon mehrfach geschrieben.
Ich habe das extra für Dich mal nachgestellt. Jetzt habe halt ich das Bild.  ::)
Gruß
Klaus
  •  

dedidado

Das hab ich doch auch schon bestätigt, ich weiß dass das nicht optimal ist, aber nicht zu ändern 🤷‍♂️

Hast du eigentlich vor zu helfen oder liegt dein Hauptaugenmerk darauf, mir zu sagen dass das falsch ist 😳

Was hab ich jetzt schon alles geschrieben und wie oft hab ich nach einer Lösung gefragt, auf dem SQL Server das löschen zu verhindern?

Und was hab ich bekommen? du hast mir bestimmt fünf mal geschrieben dass mein Datenmodell falsch ist 👏👏👏
Respekt und ganz nebenbei hast du den Thread damit kaputt gemacht oder glaubst du, das liest sich wirklich noch jemand durch 🙄
  •  

MzKlMu

#11
Hallo,
sorry, aber liest Du eigentlich was ich schreibe ?
Ich habe mich nur ein einziges mal mit einem Satz (in #5) auf das Datenmodell bezogen. Meine anderen Hinweis haben mit dem Datenmodell nichts zu tun, rein gar nichts das bleibt wie es ist. Habe auch nichts weiter dazu geschrieben.
Die Kontakttabelle muss ein zweites mal als Alias Tabelle aufgenommen werden und dann 2 getrennte Beziehungen angelegt werden. Dazu habe ich Dir das Bild eingefügt. Das ist bezogen auf das bei Dir vorliegende Datenmodell. Dann wird auch das Löschen verhindert.
Dabei bleiben alle Tabellen unverändert so wie sie jetzt sind.
Gruß
Klaus
  •  

dedidado

Mit Access ist das möglich, aber nicht mit dem SQL-Server, zumindest ist mir keine bekannt.
Im Datenbankdiagramm im Management Studio kann man jede Tabelle nur einmal hinzufügen, es gibt da kein Alias alá Kontakt_1 über den man die zweite Beziehung herstellen kann...
  •