[SQL Server] Foreign Key-Probleme > Verständnisproblem?



  • Ich habe eine Tabelle mit Benutzern einer Anwendung (IdBenutzer, Name, Vorname...). Gleichzeitig gibt es in den meisten Tabellen (so auch in der Benutzer-Tabelle) Historienfelder für den letzten Zugriff, hier unter anderem eine Referenz auf den Benutzer der den Datensatz angelegt bzw. geändert hat.

    Da es eine rein informative Spalte ist, lasse ich einen NULL-Wert zu, und dachte mir, ich mache eine Foreign Key-Verknüpfung mit "ON DELETE SET NULL". Meine Intention war, das wenn ein Benutzer gelöscht wird, das Historienfeld auf NULL gesetzt werden soll.

    Beispiel stark vereinfacht:

    CREATE TABLE [TBenutzer]
    (
      [IdBenutzer]         [int] IDENTITY(1000, 1) NOT NULL,
      [HistorieIdBenutzer] [int]                   NULL
      PRIMARY KEY([IdBenutzer])
    )
    
    ALTER TABLE [TBenutzer] ADD CONSTRAINT [TBenutzer_HistorieBenutzer]
    FOREIGN KEY ([HistorieIdBenutzer]) REFERENCES [TBenutzer] ([IdBenutzer]) ON DELETE SET NULL
    

    Dies liefert aber den Fehler:

    Meldung 1785, Ebene 16, Status 0, Zeile 1
    Das Einführen der FOREIGN KEY-Einschränkung 'TBenutzer_HistorieBenutzer' für die 'TBenutzer'-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.
    Meldung 1750, Ebene 16, Status 0, Zeile 1
    Die Einschränkung konnte nicht erstellt werden. Siehe vorherige Fehler.
    

    Vielleicht bin ich ja blind, aber ich verstehe nicht wo dies eine Schleife oder ein Kaskadierungsproblem nach sich ziehen sollte. Gibt es keine sinnvolle Möglichkeit dieses Problem abzubilden, liege ich mit meiner Überlegung völlig falsch, oder kann der SQL-Server nicht sinnvoll mit solchen Verweisen zu recht kommen?



  • Komisch, in postgres gehts. msdn empfiehlt in dem Fall Trigger:
    http://support.microsoft.com/kb/321843



  • witte schrieb:

    Komisch, in postgres gehts.

    Und auch wenn ich kein SQL-Guru bin, hätte ich das auch erwartet 😉

    witte schrieb:

    msdn empfiehlt in dem Fall Trigger:
    http://support.microsoft.com/kb/321843

    Da kommt ein kleines Zusatzproblem: Ich möchte neben den "normalen" SQL Server auch die Compact-Edition unterstützen. Und die lässt Trigger nicht zu.



  • Ich kenne keinen anderen Weg. Ich bin aber auch kein MSSQL-Guru. Zur Not wirst du auf Referenzschlüssel verzichten und mit verwaisten Links leben müssen.



  • Lösche einfach niemals User 🙂
    Oder lass den Constraint weg, und setz das Feld auch nicht auf NULL wenn User gelöscht werden.



  • hustbaer schrieb:

    Lösche einfach niemals User 🙂

    Das Smiley könnte man auch weglassen... 😉

    Ich finde das ist noch die beste Lösung von allen. Dann weiß man zumindest noch, wer es verbockt hat, auch wenn er nicht mehr da ist. Fürs GUI könnte man ja 'gelöschte' User als gelöscht markieren und einfach nicht mehr anzeigen.

    Gru0 KK



  • Killer-Kobold schrieb:

    hustbaer schrieb:

    Lösche einfach niemals User 🙂

    Das Smiley könnte man auch weglassen... 😉

    Ich finde das ist noch die beste Lösung von allen. Dann weiß man zumindest noch, wer es verbockt hat, auch wenn er nicht mehr da ist. Fürs GUI könnte man ja 'gelöschte' User als gelöscht markieren und einfach nicht mehr anzeigen.

    Solange die Historienfelder nur rein informativ sind, und man immer nur maximal die letzte Aktion ablesen kann, halte ich die Löscheinschränkung für Unsinn. Wenn man wiederum mit einer echten Historie (die für jeden Datensatzstand z.B. einen Eintrag in einer Historientabelle macht) arbeitet, sähe ich das ähnlich.

    Aber solange wir mit Clientdatenbanken wie Access oder MS SQL Server Compact arbeiten, in der keine Trigger etc. existieren, halte ich die einfache Lösung meist auch für das sinnvollste.


Anmelden zum Antworten