В 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) Добавьте в таблицу z столбцы, допускающие значение NULL,
A_ID
иB_ID
столбцы, создайтеA_or_B_ID
вычисляемый столбец с использованием ISNULL для этих двух столбцов и добавьте ограничение CHECK, чтобы только один изA_ID
илиB_ID
не был нулевым2) Добавьте столбец TableName в таблицу z, который должен содержать либо A, либо B. Теперь создайте
A_ID
иB_ID
как вычисляемые столбцы, которые не равны NULL, только если их соответствующая таблица названа (с использованием выражения CASE). Сделайте так, чтобы они тоже осталисьВ обоих случаях, теперь у вас есть ,
A_ID
иB_ID
столбцы , которые могут иметь соответствующие внешние ключи к базовым таблицам. Разница в том, какие столбцы вычисляются. Кроме того, вам не нужно TableName в варианте 2 выше, если домены двух столбцов идентификатора не перекрываются - если ваше выражение case может определить, какой доменA_or_B_ID
попадает в(Спасибо за комментарий за исправление моего форматирования)
источник
A_or_B_ID
К сожалению, вы не можете использовать FK для представления в SQL Server.
источник
Есть еще вариант. Рассматривайте TableA и TableB как подклассы новой таблицы с именем TablePrime. Настройте значения идентификатора TableB так, чтобы они не совпадали со значениями идентификатора TableA. Сделайте идентификатор в TablePrime PK и вставьте все (скорректированные) идентификаторы TableA и TableB в TablePrime. Сделайте так, чтобы TableA и TableB имели отношения FK на их PK с одним и тем же идентификатором в TablePrime.
Теперь у вас есть шаблон супертипа / подтипа, и вы можете наложить ограничения на TablePrime (когда вы хотите -A -или-B ) или одну из отдельных таблиц (когда вы хотите только A или только B ).
Если вам нужна более подробная информация, спрашивайте. Существуют варианты, которые позволят вам убедиться, что A и B являются взаимоисключающими, или, возможно, то, с чем вы работаете, может быть обоими одновременно. По возможности лучше формализовать это в ФК.
источник
Проще добавить ограничение, которое ссылается на пользовательскую функцию, которая выполняет проверку за вас, fCheckIfValueExists (columnValue), которая возвращает истину, если значение существует, и ложь, если нет.
Положительным моментом является то, что он может получать несколько столбцов, выполнять с ними вычисления, принимать нули и принимать значения, которые не точно соответствуют первичному ключу или сравниваются с результатами объединений.
Обратной стороной является то, что оптимизатор не может использовать все свои уловки с внешним ключом.
источник
Извините, в строгом смысле слова вы не можете устанавливать внешние ключи для представлений. Вот почему:
InnoDB - единственный встроенный механизм хранения MySQL, который имеет внешние ключи. Любая таблица InnoDB будет зарегистрирована в information_schema.tables с помощью engine = 'InnoDB'.
Представления, зарегистрированные в information_schema.tables, имеют механизм хранения NULL. В MySQL нет механизмов, позволяющих иметь внешние ключи в любой таблице с неопределенным механизмом хранения.
Благодаря!
источник