Могу ли я иметь внешний ключ, ссылающийся на столбец в представлении в SQL Server?

В 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? Можно ли это сделать с помощью внешнего ключа против представления?

Ответ 1

Вы не можете ссылаться на представление во внешнем ключе.

Ответ 2

В старых версиях SQL Server внешние ключи были доступны только через триггеры. Вы можете имитировать пользовательский внешний ключ, создав триггер Insert, который проверяет, появляется ли вставленное значение в одной из соответствующих таблиц.

Ответ 3

Если вам действительно нужно 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 попадает в

(Спасибо за комментарий для исправления моего форматирования)

Ответ 4

Извините, вы не можете использовать FK для представления в SQL Server.

Ответ 5

Есть еще один вариант. Обработайте TableA и TableB как подклассы новой таблицы TablePrime. Отрегулируйте значения идентификатора TableB, чтобы они не совпадали с значениями TableA ID. Сделайте идентификатор в таблицеPrime PK и вставьте все идентификаторы TableA и TableB (скорректированные) в TablePrime. В таблице TableA и TableB есть отношения FK на их ПК с тем же идентификатором в TablePrime.

Теперь у вас есть шаблон супертипа/подтипа и вы можете создавать ограничения для TablePrime (когда вы хотите либо-A-or-B), либо одну из отдельных таблиц (если вы хотите только A или только B).

Если вам нужна дополнительная информация, пожалуйста, спросите. Существуют вариации, которые позволят вам убедиться, что A и B являются взаимоисключающими, или, возможно, то, с чем вы работаете, может быть одновременно. Лучше всего формализовать это в FK, если это возможно.

Ответ 6

Легче добавить ограничение, которое ссылается на определенную пользователем функцию, которая делает для вас проверку, fCheckIfValueExists (columnValue), которая возвращает true, если значение существует, и false, если это не так.

Потенциал роста состоит в том, что он может принимать несколько столбцов, выполнять вычисления с ними, принимать значения NULL и принимать значения, которые точно не соответствуют первичному ключу или сравнивать с результатами объединений.

Даунсайд - это то, что оптимизатор не может использовать все свои внешние трюки.