5

我有一个带有链接服务器的 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。

有什么办法可以达到同样的效果吗?

4

3 回答 3

10

外键不能连接到非本地对象——它们必须引用本地表。您收到“最大前缀数”错误,因为您使用 4 部分名称 (LinkedServer.Database.Schema.Object) 引用表,而本地对象只有 3 部分名称。

其他解决方案:

  1. 将数据从源(视图的位置)复制到与您尝试添加键的表相同的服务器。您可以每小时、每天或其他方式执行此操作,具体取决于源数据更改的频率。
  2. 在源表上添加触发器以将任何更改推送到本地副本。这基本上与 #1 相同,但会立即进行更改
  3. 向您的表添加一个 INSTEAD OF" 触发器,该触发器通过从链接服务器中选择并比较您尝试插入/更新的值来手动检查外键约束。如果不匹配,您可以拒绝更改。
于 2009-01-14T14:47:16.813 回答
1

你可以,但你必须使用一些动态的 SQL 技巧来实现它。

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

exec YourServer.master.dbo.sp_executesql @SQL
于 2009-02-04T02:28:11.090 回答
0

不,必须针对用户表创建外键。你试过下面的吗?

alter table [baz] with check 
add constraint [fk1_baz_to_foo] 
FOREIGN KEY([foo_id]) 
references 
   LINKEDSERVER.RemoteDatabase.dbo.tbl_bar([id])
go
于 2009-01-14T11:10:11.247 回答