Dans SQL Server 2008 et donné
TableA(A_ID, A_Data)
TableB(B_ID, B_Data)
ViewC(A_or_B_ID, A_or_B_Data)
est-il possible de définir de TableZ(A_or_B_ID, Z_Data)
telle sorte que la Z.A_or_B_ID
colonne soit contrainte aux valeurs trouvées dans ViewC
? Cela peut-il être fait avec une clé étrangère contre la vue?
Dans les anciennes éditions de SQL Server, les clés étrangères n'étaient possibles que via des déclencheurs. Vous pouvez imiter une clé étrangère personnalisée en créant un déclencheur d'insertion qui vérifie si la valeur insérée apparaît également dans l'une des tables pertinentes.
la source
Si vous avez vraiment besoin
A_or_B_ID
de TableZ, vous avez deux options similaires:1) Ajoutez des colonnes Nullable
A_ID
etB_ID
à la table z, créezA_or_B_ID
une colonne calculée en utilisant ISNULL sur ces deux colonnes, et ajoutez une contrainte CHECK de telle sorte qu'un seul parmiA_ID
ouB_ID
ne soit pas nul2) Ajoutez une colonne TableName à la table z, contrainte de contenir A ou B. maintenant créez
A_ID
etB_ID
sous forme de colonnes calculées, qui ne sont non nulles que lorsque leur table appropriée est nommée (en utilisant l'expression CASE). Faites-les persister aussiDans les deux cas, vous disposez désormais de colonnes
A_ID
etB_ID
qui peuvent avoir des clés étrangères appropriées pour les tables de base. La différence réside dans les colonnes calculées. De plus, vous n'avez pas besoin de TableName dans l'option 2 ci-dessus si les domaines des 2 colonnes d'ID ne se chevauchent pas - tant que votre expression de cas peut déterminer dans quel domaineA_or_B_ID
appartient(Merci au commentaire pour avoir corrigé ma mise en forme)
la source
A_or_B_ID
Désolé, vous ne pouvez pas FK sur une vue dans SQL Server.
la source
Il y a une autre option. Traitez TableA et TableB comme des sous-classes d'une nouvelle table appelée TablePrime. Ajustez les valeurs d'ID de TableB afin qu'elles ne coïncident pas avec les valeurs d'ID de TableA. Faites de l'ID dans TablePrime le PK et insérez tous les ID (ajustés) de TableA et TableB dans TablePrime. Faire en sorte que TableA et TableB aient des relations FK sur leur PK avec le même ID dans TablePrime.
Vous avez maintenant le modèle de supertype / sous-type et pouvez créer des contraintes sur TablePrime (lorsque vous voulez soit-A-ou-B ) ou l'une des tables individuelles (lorsque vous voulez seulement A ou seulement B ).
Si vous avez besoin de plus de détails, veuillez demander. Il existe des variantes qui vous permettront de vous assurer que A et B sont mutuellement exclusifs, ou peut-être que la chose avec laquelle vous travaillez peut être les deux en même temps. Il est préférable de formaliser cela dans les FK si possible.
la source
Il est plus facile d'ajouter une contrainte qui fait référence à une fonction définie par l'utilisateur qui effectue la vérification pour vous, fCheckIfValueExists (columnValue) qui renvoie true si la valeur existe et false si ce n'est pas le cas.
L'avantage est qu'il peut recevoir plusieurs colonnes, effectuer des calculs avec elles, accepter des valeurs nulles et accepter des valeurs qui ne correspondent pas précisément à une clé primaire ou se comparer aux résultats des jointures.
L'inconvénient est que l'optimiseur ne peut pas utiliser toutes ses astuces de clé étrangère.
la source
Désolé, au sens strict du terme, non, vous ne pouvez pas définir de clés étrangères sur les vues. Voici pourquoi:
InnoDB est le seul moteur de stockage intégré pour MySQL qui comporte des clés étrangères. Toute table InnoDB sera enregistrée dans information_schema.tables avec engine = 'InnoDB'.
Les vues, bien qu'elles soient enregistrées dans information_schema.tables, ont un moteur de stockage NULL. Il n'y a aucun mécanisme dans MySQL pour avoir des clés étrangères sur une table qui a un moteur de stockage non défini.
Merci!
la source