Связь внешнего ключа SQL Server с двумя таблицами

У меня есть БД, в которой 3 таблицы имеют отношения FK, поскольку:

Таблица A содержит 2 (соответствующих) поля:
TypeId (int)
LinkId (int)

Таблицы B и C имеют первичный ключ, который сопоставляется с LinkId в таблице A. Если TypeId в таблице A равен 1, то LinkId сопоставляется с первичным ключом в таблице B. Если он равен 2, он сопоставляется с первичным ключом в таблице. С.

Можно ли в этой плохо спроектированной БД обеспечить ссылочную целостность этих таблиц? т. е. Можно ли запретить SQL Server вставлять запись в таблицу A, если соответствующая запись не существует в таблицах B или C?


person Guy    schedule 06.05.2012    source источник
comment
Я предполагаю, что это было бы возможно с триггерами before, но их правильное построение нетривиально. Есть ли возможность изменить дизайн таблиц?   -  person Mikael Eriksson    schedule 06.05.2012
comment
Итак, внешние ключи от TBL_A до B или C? ИЛИ из B, C в A? Не могли бы вы опубликовать определение внешних ключей?   -  person Damir Sudarevic    schedule 06.05.2012


Ответы (1)


Вы можете использовать две новые таблицы ссылок и удалить LinkId из таблицы A.

AB (Aid, Bid)
AC (Aid, Cid)

Однако зависит от вашего приложения и от вашего контроля над вставкой...

Вам не нужно использовать встроенные ограничения — вы, конечно, можете написать собственные ограничения с триггерами, если хотите сохранить эту структуру.

что-то типа:

   CREATE TRIGGER trigger_name ON A
      FOR INSERT, UPDATE

      AS

     declare @err varchar(50)

     select @err = case 
       when inserted.typeid = 1 and not exists(select 0 from B where id=inserted.linkid) then
            @err = 'No link record exists in B.'
       when inserted.typeid = 2 and not exists(select 0 from C where id=inserted.linkid) then
            @err = 'No link record exists in C.'
       else @err = null     
      end
      from inserted

     if @err is not null RAISERROR (@err, 16, 1 )
person jenson-button-event    schedule 06.05.2012