Можете ли вы иметь внешний ключ для представления таблицы связанного сервера в SQLServer 2k5?

У меня есть SQLServer со связанным сервером в другой базе данных где-то еще. Я создал представление на этом связанном сервере

create view vw_foo as
select
[id],
[name]
from LINKEDSERVER.RemoteDatabase.dbo.tbl_bar

я хотел бы к следующему

alter table [baz] 
add foo_id int not null
go

alter table [baz] with check 
add constraint [fk1_baz_to_foo] 
  foreign key([foo_id]) 
  references [dbo].[vw_foo] ([id])
go

Но это вызывает ошибку: «Внешний ключ 'fk1_baz_to_foo' ссылается на объект 'dbo.vw_foo', который не является пользовательской таблицей».

Если я попытаюсь поместить внешний ключ прямо в таблицу, используя следующее

alter table [baz] with check 
add constraint [fk1_baz_to_bar] 
  foreign key([foo_id]) 
  references LINKEDSERVER.RemoteDatabase.dbo.tbl_bar ([id])

Затем я получаю следующую ошибку:

Имя объекта «LINKEDSERVER.RemoteDatabase.dbo.tbl_bar» содержит больше префиксов, чем максимальное количество. Максимум 2.

Можно ли как-то добиться такого же эффекта?


person d4nt    schedule 14.01.2009    source источник
comment
Да: внешний ключ 'fk1_baz_to_foo' ссылается на объект 'dbo.vw_foo', который не является пользовательской таблицей.   -  person d4nt    schedule 14.01.2009


Ответы (3)


Внешние ключи нельзя связывать с нелокальными объектами — они должны ссылаться на локальные таблицы. Вы получаете ошибку «максимальное количество префиксов», потому что вы ссылаетесь на таблицу с именем из 4 частей (LinkedServer.Database.Schema.Object), а локальный объект будет иметь только имя из 3 частей.

Другие решения:

  1. Реплицируйте данные из источника (расположение представления) на тот же сервер, что и таблица, в которую вы пытаетесь добавить ключ. Вы можете делать это ежечасно, ежедневно или как угодно, в зависимости от того, как часто меняются исходные данные.
  2. Добавьте триггер в исходную таблицу, чтобы передать любые изменения в вашу локальную копию. По сути, это будет то же самое, что и № 1, но с немедленным внесением изменений.
  3. Добавьте в свою таблицу триггер INSTEAD OF", который вручную проверяет ограничение внешнего ключа, выбирая на связанном сервере и сравнивая значение, которое вы пытаетесь ВСТАВИТЬ/ОБНОВИТЬ. Если оно не совпадает, вы можете отклонить изменение.
person SqlRyan    schedule 14.01.2009

Вы можете, но вам нужно использовать некоторые трюки с динамическим SQL, чтобы это произошло.

declare @cmd VARCHAR(4000)
SET @cmd = 'Use YourDatabase
ALTER TABLE YourTable
DROP CONSTRAINT YourConstraint'

exec YourServer.master.dbo.sp_executesql @SQL
person mrdenny    schedule 04.02.2009

Нет, внешние ключи должны быть созданы для пользовательских таблиц. Вы пробовали ниже?

alter table [baz] with check 
add constraint [fk1_baz_to_foo] 
FOREIGN KEY([foo_id]) 
references 
   LINKEDSERVER.RemoteDatabase.dbo.tbl_bar([id])
go
person cmsjr    schedule 14.01.2009
comment
Да, это ошибки: Имя объекта «LINKEDSERVER.RemoteDatabase.dbo.tbl_bar» содержит больше максимального количества префиксов. Максимум 2. - person d4nt; 14.01.2009
comment
Ссылки внешних ключей между базами данных не поддерживаются! - person bjnr; 13.11.2013