W SQL Server 2008 i podane
TableA(A_ID, A_Data)
TableB(B_ID, B_Data)
ViewC(A_or_B_ID, A_or_B_Data)
czy można zdefiniować TableZ(A_or_B_ID, Z_Data)
takie, że Z.A_or_B_ID
kolumna jest ograniczona do wartości znajdujących się w ViewC
? Czy można to zrobić za pomocą klucza obcego w widoku?
sql-server
view
foreign-keys
marc
źródło
źródło
W starszych wersjach SQL Server klucze obce były możliwe tylko poprzez wyzwalacze. Możesz naśladować niestandardowy klucz obcy, tworząc wyzwalacz wstawiania, który sprawdza, czy wstawiona wartość pojawia się również w jednej z odpowiednich tabel.
źródło
Jeśli naprawdę potrzebujesz
A_or_B_ID
w TableZ, masz dwie podobne opcje:1) Dodaj wartość null
A_ID
iB_ID
kolumny do tabeli z, utwórzA_or_B_ID
kolumnę obliczaną za pomocą ISNULL na tych dwóch kolumnach i dodaj ograniczenie CHECK takie, że tylko jeden z nichA_ID
lubB_ID
nie jest pusty2) Dodaj kolumnę TableName do tabeli z, ograniczoną tak, aby zawierała A lub B. Teraz utwórz
A_ID
iB_ID
jako kolumny obliczeniowe, które mają wartość różną od null tylko wtedy, gdy zostanie nazwana odpowiednia tabela (używając wyrażenia CASE). Niech też się utrzymująW obu przypadkach masz teraz kolumny
A_ID
i,B_ID
które mogą mieć odpowiednie klucze obce do tabel podstawowych. Różnica polega na tym, które kolumny są obliczane. Nie potrzebujesz również TableName w opcji 2 powyżej, jeśli domeny dwóch kolumn ID nie nakładają się - o ile wyrażenie przypadku może określić, do której domenyA_or_B_ID
należy(Dzięki komentarzowi za naprawienie mojego formatowania)
źródło
A_or_B_ID
Przepraszamy, nie można FK do widoku w programie SQL Server.
źródło
Jest inna opcja. Traktuj TableA i TableB jako podklasy nowej tabeli o nazwie TablePrime. Dostosuj wartości identyfikatora TableB, aby nie pokrywały się z wartościami identyfikatora TableA. Utwórz identyfikator w TablePrime jako PK i wstaw wszystkie identyfikatory TableA i TableB (dostosowane) do TablePrime. Spraw, aby TableA i TableB miały relacje FK na ich PK z tym samym identyfikatorem w TablePrime.
Masz teraz wzorzec nadtypu / podtypu i możesz tworzyć ograniczenia do TablePrime (gdy chcesz albo A-albo-B ) lub jednej z pojedynczych tabel (gdy chcesz tylko A lub tylko B ).
Jeśli potrzebujesz więcej informacji, zapytaj. Istnieją odmiany, które pozwolą Ci upewnić się, że A i B wzajemnie się wykluczają, a może to, z czym pracujesz, może być jednym i drugim w tym samym czasie. Najlepiej sformalizować to w FK, jeśli to możliwe.
źródło
Łatwiej jest dodać ograniczenie, które odwołuje się do funkcji zdefiniowanej przez użytkownika, która wykonuje sprawdzenie za Ciebie, fCheckIfValueExists (columnValue), które zwraca true, jeśli wartość istnieje, i false, jeśli nie.
Zaletą jest to, że może odbierać wiele kolumn, wykonywać z nimi obliczenia, akceptować wartości null i akceptować wartości, które nie odpowiadają dokładnie kluczowi głównemu lub porównują się z wynikami łączenia.
Wadą jest to, że optymalizator nie może wykorzystać wszystkich swoich sztuczek z kluczami obcymi.
źródło
Przepraszamy, w ścisłym znaczeniu tego słowa, nie, nie możesz ustawić kluczy obcych w widokach. Oto dlaczego:
InnoDB to jedyny wbudowany mechanizm przechowywania danych dla MySQL, który obsługuje klucze obce. Każda tabela InnoDB zostanie zarejestrowana w information_schema.tables z silnikiem = 'InnoDB'.
Widoki, mimo że są zarejestrowane w information_schema.tables, mają NULL silnik magazynu. W MySQL nie ma mechanizmów, które pozwalałyby na umieszczanie kluczy obcych w dowolnej tabeli z niezdefiniowanym silnikiem przechowywania.
Dzięki!
źródło