【发布时间】:2011-05-12 07:31:32
【问题描述】:
只要事务尚未提交,SQL Server 是否允许在事务中违反约束(即延迟约束)?
我有一个正在运行的、未提交的事务,当这个事务正在运行时,我将更改我的数据,以使其违反某些约束(例如具有重复的主键)。当我提交事务时,数据将处于一致、有效的状态。这通常在 SQL 中,特别是在 MS SQL Server 中允许吗?
【问题讨论】:
标签: sql sql-server transactions constraints
只要事务尚未提交,SQL Server 是否允许在事务中违反约束(即延迟约束)?
我有一个正在运行的、未提交的事务,当这个事务正在运行时,我将更改我的数据,以使其违反某些约束(例如具有重复的主键)。当我提交事务时,数据将处于一致、有效的状态。这通常在 SQL 中,特别是在 MS SQL Server 中允许吗?
【问题讨论】:
标签: sql sql-server transactions constraints
不,对不起。 SQL Server 不允许事务中的延迟约束。它存在于 SQL Server 6.5 中,但在 SQL Server 2000 中被删除:
SET DISABLE_DEF_CNST_CHK ON
每个单独的语句必须一致等,无论它是否在事务中
一些 RDBMS 确实允许这样做(例如 Oracle、Postgres、Interbase)
有一个Microsoft Connect request,创建于 2006 年,要求提供此功能:
将外键约束检查推迟到事务提交的选项
在各种“鸡和蛋”场景中,最好将参照完整性约束的检查推迟到事务的提交时间。
允许将参照完整性约束检查推迟到事务的提交时间(作为一个选项)。建议在 BEGIN TRANSACTION 上提供一个选项来指定这一点。
微软的最后一次回应是在十年前:
由 Sameer [MSFT] 于 2006 年 10 月 13 日下午 1:35 发布
你好,格雷格,
感谢您的反馈。我们已经意识到这一点,并正在研究它以供将来发布。
Sameer Verkhedkar
SQL 引擎
[微软]
微软代表“走开”。
该功能在July 1992 with SQL-92 中定义。一个示例语法是:
BEGIN TRANSACTION
SET CONSTRAINTS ALL DEFERRED --applies only to the current transaction
INSERT Customers ...
INSERT Orders ...
UPDATE Customers ... --add the thing we were missing
COMMIT TRANSACTION
【讨论】:
您可以在运行事务时禁用约束,然后在完成后重新启用它们。
ALTER TABLE mytable NOCHECK CONSTRAINT myconstraint
--... RUN TRANSACTION
ALTER TABLE mytable WITH CHECK CHECK CONTRAINT ALL
警告:这将影响所有连接。
【讨论】:
如果必须(例如从导入文件中清理数据的流程),则将中间数据放入临时表或表变量或暂存表中,然后仅对具有约束的真实表执行操作清理它并使数据正确。
【讨论】:
CHECK 约束 - 而不是 FOREIGN KEY 约束,这是真正令人头疼的地方(例如 1:1 关系、自引用表、循环图数据库、多态表、表中的子类等)。
SQL Server 没有延迟约束选项。但在某些情况下,您可以使用支持忽略约束而不会出现禁用问题的批量插入。有关更多信息,您可以查看以下链接:
那么在提交事务之前,你将不得不手动检查整个表的约束。
【讨论】: