Ответ 1
Вы не можете ссылаться на представление во внешнем ключе.
В SQL Server 2008 и с учетом
TableA(A_ID, A_Data)
TableB(B_ID, B_Data)
ViewC(A_or_B_ID, A_or_B_Data)
можно ли определить TableZ(A_or_B_ID, Z_Data)
так, чтобы столбец Z.A_or_B_ID
был привязан к значениям, найденным в ViewC
? Можно ли это сделать с помощью внешнего ключа против представления?
Вы не можете ссылаться на представление во внешнем ключе.
В старых версиях SQL Server внешние ключи были доступны только через триггеры. Вы можете имитировать пользовательский внешний ключ, создав триггер Insert, который проверяет, появляется ли вставленное значение в одной из соответствующих таблиц.
Если вам действительно нужно A_or_B_ID
в TableZ, у вас есть два похожих варианта:
1) Добавьте столбцы с нулевым значением A_ID
и B_ID
в таблицу z, сделайте A_or_B_ID
вычисленный столбец, используя ISNULL в этих двух столбцах, и добавьте ограничение CHECK, чтобы только один из A_ID
или B_ID
не является нулевым
2) Добавьте столбец TableName в таблицу z, который должен содержать A или B. Теперь создайте A_ID
и B_ID
в качестве вычисленных столбцов, которые являются только ненулевыми, когда их соответствующая таблица названа (с использованием выражения CASE). Сделайте их еще слишком стойкими.
В обоих случаях у вас теперь есть столбцы A_ID
и B_ID
, которые могут иметь соответствующие внешние
ключи к базовым таблицам. Разница в том, какие столбцы вычисляются. Вас также
не нужно TableName в варианте 2 выше, если домены из двух столбцов ID не
наложение - если выражение вашего случая может определить, какой домен A_or_B_ID
попадает в
(Спасибо за комментарий для исправления моего форматирования)
Извините, вы не можете использовать FK для представления в SQL Server.
Есть еще один вариант. Обработайте TableA и TableB как подклассы новой таблицы TablePrime. Отрегулируйте значения идентификатора TableB, чтобы они не совпадали с значениями TableA ID. Сделайте идентификатор в таблицеPrime PK и вставьте все идентификаторы TableA и TableB (скорректированные) в TablePrime. В таблице TableA и TableB есть отношения FK на их ПК с тем же идентификатором в TablePrime.
Теперь у вас есть шаблон супертипа/подтипа и вы можете создавать ограничения для TablePrime (когда вы хотите либо-A-or-B), либо одну из отдельных таблиц (если вы хотите только A или только B).
Если вам нужна дополнительная информация, пожалуйста, спросите. Существуют вариации, которые позволят вам убедиться, что A и B являются взаимоисключающими, или, возможно, то, с чем вы работаете, может быть одновременно. Лучше всего формализовать это в FK, если это возможно.
Легче добавить ограничение, которое ссылается на определенную пользователем функцию, которая делает для вас проверку, fCheckIfValueExists (columnValue), которая возвращает true, если значение существует, и false, если это не так.
Потенциал роста состоит в том, что он может принимать несколько столбцов, выполнять вычисления с ними, принимать значения NULL и принимать значения, которые точно не соответствуют первичному ключу или сравнивать с результатами объединений.
Даунсайд - это то, что оптимизатор не может использовать все свои внешние трюки.