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

У меня есть 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.

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

Ответы [ 3 ]

10 голосов
/ 14 января 2009

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

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

  1. Реплицируйте данные из источника (расположение представления) на тот же сервер, что и таблица, к которой вы пытаетесь добавить ключ. Вы можете делать это ежечасно, ежедневно или как угодно, в зависимости от того, как часто меняются исходные данные.
  2. Добавьте триггер в исходную таблицу для отправки любых изменений в вашу локальную копию. По сути, это будет то же самое, что и # 1, но с немедленным заполнением изменений
  3. Добавьте в вашу таблицу триггер INSTEAD OF ", который вручную проверяет ограничение внешнего ключа, выбирая на связанном сервере и сравнивая значение, которое вы пытаетесь вставить / обновить. Если оно не совпадает, вы можете отклонить изменение .
1 голос
/ 04 февраля 2009

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

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

exec YourServer.master.dbo.sp_executesql @SQL
0 голосов
/ 14 января 2009

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

alter table [baz] with check 
add constraint [fk1_baz_to_foo] 
FOREIGN KEY([foo_id]) 
references 
   LINKEDSERVER.RemoteDatabase.dbo.tbl_bar([id])
go
...