SQL Server 2016 无法将系统版本控制添加到关系表
Posted
技术标签:
【中文标题】SQL Server 2016 无法将系统版本控制添加到关系表【英文标题】:SQL Server 2016 Cannot add system versioning to relationship table 【发布时间】:2016-10-10 14:41:20 【问题描述】:SQL Server 2016 系统版本控制很酷。我正在使用免费的开发者版本。谢谢女士!
我无法弄清楚它是否会给我多对多关系的版本控制。我有一个包含角色集合的用户对象,反之亦然。 Entity Framework 已生成 UserRoles
表,其中包含 User
和 Roles
之间的关系。我能够使用这篇文章http://sqlhints.com/tag/modify-existing-table-as-system-versioned-temporal-table/ 为User
和Roles
表打开系统版本控制。
但是,我无法打开UserRoles
。我收到一个错误
将 SYSTEM_VERSIONING 设置为 ON 失败,因为表有一个 FOREIGN KEY 和级联 DELETE 或 UPDATE。
这是否意味着我们无法知道多对多关系的版本控制?
例如。
6 月 1 日 - 用户 1 有角色 1 和角色 2,但是 6 月 4 日 - 用户 1 的角色更改为角色 1 和角色 3所以,如果我想知道用户在 6 月 1 日的状态,我认为只有在 UserRoles
上打开系统版本控制才能实现,但这不起作用。
SQL Server 2016 是否支持此操作?如果没有,还有其他方法可以实现吗?
【问题讨论】:
听起来问题出在 ON UPDATE CASCADE 或 ON UPDATE DELETE 外键上。删除级联并将其替换为知道并处理正确关系的删除过程,您应该没问题。 这就是我们最终所做的。非常感谢!想知道如何将其标记为答案。 我会把它放到“答案”部分,这样它就可以显示为已回答。 :) 【参考方案1】:请务必注意,在时态表中对 FOREIGN KEY
约束使用 CASCADE
的限制仅适用于 SQL Server 2016。在 SQL Server 2017 中,此限制不再存在。
这是来自official documentation的相关部分:
ON DELETE CASCADE 和 ON UPDATE CASCADE 不允许在 当前表。换句话说,当临时表正在引用时 表中的外键关系(对应 parent_object_id in sys.foreign_keys) 不允许使用 CASCADE 选项。 要解决此限制,请使用应用程序逻辑或之后 触发器以保持主键表中删除的一致性 (对应于 sys.foreign_keys 中的 referenced_object_id)。如果 主键表是临时的,引用表是非临时的, 没有这样的限制。
> 注意:此限制仅适用于 SQL Server 2016。级联选项 从 CTP 开始在 SQL 数据库和 SQL Server 2017 中受支持 2.0.
【讨论】:
确实如此。我已经按照您的建议编辑了我的答案。谢谢。【参考方案2】:听起来问题出在 ON UPDATE CASCADE 或 ON UPDATE DELETE 外键上。删除级联并将其替换为知道并处理正确关系的删除过程,您应该没问题。
就个人而言,我喜欢知道我的删除/更新在做什么,而不是信任关系来处理所有这些。我可以看到潜在的锁定问题,并且知道有时我真的想阻止更新或删除,而不是让它通过所有看不见的表级联。
【讨论】:
【参考方案3】:在当前表上不允许 ON DELETE CASCADE 和 ON UPDATE CASCADE。换句话说,当临时表在外键关系中引用表时(对应于 sys.foreign_keys 中的 parent_object_id),不允许使用 CASCADE 选项。要解决此限制,请使用应用程序逻辑或后触发器来保持主键表中删除的一致性(对应于 sys.foreign_keys 中的 referenced_object_id)。如果主键表是临时表,而引用表是非临时表,则没有这个限制。
【讨论】:
以上是关于SQL Server 2016 无法将系统版本控制添加到关系表的主要内容,如果未能解决你的问题,请参考以下文章
我装sql server2016失败了, 现在想安装2014版,需要先将2016卸载吗
安装数据库sql server2019时,到最后提示服务没有及时响应启动或控制请求,怎么办?
SQL server 2016可以安装在win7系统上吗?要安装啥虚拟机??