In SQL Server 2008 und gegeben
TableA(A_ID, A_Data)
TableB(B_ID, B_Data)
ViewC(A_or_B_ID, A_or_B_Data)
ist es möglich, TableZ(A_or_B_ID, Z_Data)
so zu definieren, dass die Spalte Z.A_or_B_ID
auf die Werte in ViewC
beschränkt ist? Kann dies mit einem Fremdschlüssel gegen die Ansicht erfolgen?
Sie können nicht auf eine Ansicht in einem Fremdschlüssel verweisen.
In älteren SQL Server-Editionen waren Fremdschlüssel nur über Trigger möglich. Sie können einen benutzerdefinierten Fremdschlüssel imitieren, indem Sie einen Insert-Trigger erstellen, der prüft, ob der eingefügte Wert auch in einer der relevanten Tabellen angezeigt wird.
Wenn Sie wirklich brauchen A_or_B_ID
In TableZ haben Sie zwei ähnliche Optionen:
1) Add nullable A_ID
und B_ID
Spalten zu Tabelle z, machen A_or_B_ID
eine berechnete Spalte, in der ISNULL für diese beiden Spalten verwendet wird, und fügen Sie eine CHECK-Einschränkung hinzu, sodass nur eine von A_ID
oder B_ID
ist nicht null
2) Fügen Sie der Tabelle z eine TableName-Spalte hinzu, die entweder A oder B enthalten darf. Jetzt erstellen Sie A_ID
und B_ID
als berechnete Spalten, die nur dann ungleich Null sind, wenn ihre entsprechende Tabelle benannt ist (unter Verwendung des CASE-Ausdrucks). Lassen Sie sie auch bestehen
In beiden Fällen haben Sie jetzt A_ID
und B_ID
Spalten, die entsprechende Fremdschlüssel zu den Basistabellen haben können. Der Unterschied besteht darin, in welchen Spalten berechnet wird. Außerdem benötigen Sie in Option 2 oben keinen Tabellennamen, wenn sich die Domänen der 2 ID-Spalten nicht überlappen - vorausgesetzt, Ihr case-Ausdruck kann bestimmen, welche Domäne A_or_B_ID
fällt in
(Danke an den Kommentar zum Korrigieren meiner Formatierung)
Es tut uns leid, Sie können nicht zu einer Ansicht in SQL Server FK.
Es gibt noch eine andere Option. Behandeln Sie TableA und TableB als Unterklassen einer neuen Tabelle mit dem Namen TablePrime. Passen Sie die ID-Werte von TableB so an, dass sie nicht mit den ID-Werten von TableA übereinstimmen. Machen Sie die ID in TablePrime zur PK und fügen Sie alle (angepassten) IDs von TableA und TableB in TablePrime ein. Stellen Sie sicher, dass TableA und TableB auf ihrer PK FK-Beziehungen zu derselben ID in TablePrime haben.
Sie haben jetzt das Supertype/Subtype-Muster und können Einschränkungen für TablePrime (wenn Sie möchten entweder-A-oder-B) oder eine der einzelnen Tabellen (wenn Sie möchten nur A) festlegen oder nur B).
Wenn Sie weitere Informationen benötigen, fragen Sie bitte. Es gibt Variationen, mit denen Sie sicherstellen können, dass A und B sich gegenseitig ausschließen, oder vielleicht kann das, mit dem Sie arbeiten, beides gleichzeitig sein. Es ist am besten, dies in den FKs zu formalisieren, wenn dies möglich ist.
Entschuldigung, im engeren Sinne des Wortes können Sie keine Fremdschlüssel für Ansichten festlegen. Hier ist warum:
InnoDB ist die einzige integrierte Speicher-Engine für MySQL, die Fremdschlüssel enthält. Jede InnoDB-Tabelle wird in information_schema.tables mit engine = 'InnoDB' registriert.
Views, die in information_schema.tables registriert sind, verfügen über eine NULL-Speicher-Engine. In MySQL gibt es keine Mechanismen, um Fremdschlüssel in einer Tabelle mit einer undefinierten Speicher-Engine zu haben.
Vielen Dank!
Es ist einfacher, eine Einschränkung hinzuzufügen, die auf eine benutzerdefinierte Funktion verweist, die die Prüfung für Sie durchführt. FCheckIfValueExists (columnValue) gibt true zurück, wenn der Wert vorhanden ist, und false, wenn dies nicht der Fall ist.
Der Vorteil ist, dass mehrere Spalten empfangen, Berechnungen mit ihnen durchgeführt, Nullen akzeptiert und Werte akzeptiert werden können, die nicht genau einem Primärschlüssel entsprechen oder mit den Ergebnissen von Verknüpfungen verglichen werden können.
Nachteil ist, dass der Optimierer nicht alle seine Fremdschlüssel-Tricks anwenden kann.