【问题标题】:SQL Foreign Key in Another Database另一个数据库中的 SQL 外键
【发布时间】:2014-06-03 16:07:31
【问题描述】:

我目前正在创建一个数据库,它本质上是另一个数据库的子数据库。当我们的客户获得我们的软件时,他们会获得一个数据库,我们称之为 MasterBase。该数据库包含两个不同的小型数据库的架构,我们称它们为 MasterC 和 MasterF。

我的工作是获取与 MasterF 相关的所有模式并将它们放入自己的数据库中。问题是 MasterC 中有很多对表和视图的引用。为了解决这个问题,我将添加一个将 MasterF 与 MasterC 配对的属性,以便在我的 .NET 解决方案中我应该能够执行以下操作:

表 tableName....(在 MasterF 中创建表) 参考文献 .... MasterC.dbo.tableC(MasterC 中的表)

但是,在 SQL 中,这会引发错误:不支持 MSG 1763 跨数据库外键引用。

我已经阅读了最常见的解决方法是添加一个触发器,但是看到这并不安全并且有很多这样的实例我想知道是否还有其他方法,也许是存储过程或类似的东西.

如果触发器确实是最好/唯一的方法,并且我必须为每个有此问题的表添加触发器,我将如何编写此触发器,我知道一点 SQL,但几乎不精通。

请帮忙!

【问题讨论】:

  • 引发错误的实际代码是什么?
  • FK 不能配合,编写一组触发器来做同样的事情会让人头疼。这背后的原因是为了分离文件吗?您可以将表分配给备用数据库文件并独立移动它们。
  • 分离数据库的目的是让它们可以单独构建。因此,有些客户可能需要两者,而有些客户可能只需要其中一个。如果客户需要独立的 MasterF,我正在创建的工具将通过简单地不构建引用 MasterC 的模式来解决此问题。但是,如果两者都需要,则保证 MasterC 存在,因此可以引用。
  • 为什么不建立合适的数据库:C、F 和 C+F?
  • 这就是我想要做的,但是如果不引用 C 的某些模式,我就无法构建 F... C+F 是标准,因为它们密切相关,这是一个新功能我正在处理的客户。我想我不明白你在问什么,因为这几乎就是我想要问的......

标签: sql database sql-server-2008 foreign-keys cross-database


【解决方案1】:
  • 触发器(正如您提到的)...
  • 数据库分区...
  • 从 MasterC 复制表(它们是事务性的吗?它们多久更新一次?MasterC 是否需要更新?如果需要,您是否允许通过“作业”等每 24 小时更新一次副本? )

根据您对个人构建的最后评论,我想我会说客户“需要”两者的阈值是当他们......嗯,“需要”两者时。听起来您几乎需要第三种模式,对于不引用 MasterF 的 MasterC 中的表,对于您归类为不需要两者的客户端。

顺便说一句——这都是关于参照完整性的,是吗?除了“关系”之外,您还可以采用其他策略来实现该目标。

编辑

CREATE TRIGGER myTrigger ON myTable
AFTER INSERT
AS
IF NOT EXISTS (SELECT * FROM OtherDatabase.otherschema.othertable F
           JOIN inserted AS i 
           ON F.KeyYouAreLookingFor = i.KeyYouHave)
BEGIN
RAISERROR ('Lookup Value Not Found -- Insert Failed', 16, 1);
ROLLBACK TRANSACTION;
RETURN 
END;

【讨论】:

  • 我将如何构建一个引用另一个没有外键关系的表的表。关于您提到的第三个模式,我将向模式添加扩展属性,可用于确定何时需要构建表。我也无法将 MasterC 中的表添加到 MasterF,这几乎完全违背了目的。我不确定数据库分区是什么,就像我说的那样,我有点“菜鸟”。
  • 您确实需要 FK 才能查询。它允许 DBMS 强制引用表中的值出现在被引用表中并进行优化。如果您有同义词,您至少可以检查引用列上的投影是否是引用列上的投影的子集。 FK 的引用列也应该是键或唯一的事实无论如何都是多余的(逻辑上但不是为了优化)。
  • @user3662475——就个人而言,我倾向于使用触发器——这似乎是最可靠的选择。我已经编辑了我的答案,以便您了解如何完成。
  • 非常感谢您的回答!我肯定会使用触发器,因为这似乎是最好的方法。另外,感谢您提供的示例,正​​如我所说,我是 SQL 领域的新手,可能会花很多时间学习如何编写它们。非常感谢!
猜你喜欢
  • 1970-01-01
  • 2016-10-17
  • 2018-07-19
  • 2023-03-23
  • 2016-08-18
  • 1970-01-01
  • 2020-05-13
  • 2012-05-31
  • 2022-01-17
相关资源
最近更新 更多