Sql 启用约束
我有一个有很多约束的大型数据库,我更新了一些数据禁用约束,我只想重新启用它们 我使用了下面的查询Sql 启用约束,sql,sql-server,tsql,sql-server-2000,Sql,Sql Server,Tsql,Sql Server 2000,我有一个有很多约束的大型数据库,我更新了一些数据禁用约束,我只想重新启用它们 我使用了下面的查询 EXEC sp_msforeachtable 'ALTER TABLE MyTable NOCHECK CONSTRAINT all' exec sp_msforeachtable @command1='print ''MyTable''', @command2='ALTER TABLE MyTable WITH CHECK CHECK CONSTRAINT all' 但是,当我运行enable
EXEC sp_msforeachtable 'ALTER TABLE MyTable NOCHECK CONSTRAINT all'
exec sp_msforeachtable @command1='print ''MyTable''', @command2='ALTER TABLE MyTable WITH CHECK CHECK CONSTRAINT all'
但是,当我运行enable查询时,由于数据量巨大,需要很长时间。花了一个多小时
我只想以正确的方式快速启用它,而不会出现任何问题
请指导我如何克服这个问题。以“正确的方式而不出现任何问题”来解决这个问题需要时间。您可以通过省略
WITH CHECK
选项来提高速度,但最终会在数据库中出现,因此我不建议使用该选项。需要检查的一件事是,约束两侧是否都有索引(顺便说一句,在正常操作中这是个好主意)。为了明确这一点,假设您有两个表(tbl_a和tbl_b),它们之间有FK约束(假设它是col_c)。您需要一个索引,其中前导列在tbl_a和tbl_b上都是col_c,这样它就不必对没有这样一个索引的表进行表扫描
此外,单独检查每个约束(而不是做一个“检查约束全部”)将为您提供更好的粒度,如果您需要在中间停止。
< P>使用SPMsMealCabSt表顺序运行语句。最有可能的是,将事情分散在几个线程上会大大加快进程。使用ServiceBroker,这可以在SQL代码中完成 (下面是从内存中编写的代码,我没有可用的SQL Server来测试它。因此,其中可能有一些错误。只要有可用的服务器,我就会更新。) 首先创建一个激活过程 CREATE PROC p_enable_constraints
AS
DECLARE @handle UNIQUEIDENTIFIER
, @message sysname
, @sql nvarchar(max)
WHILE 1=1
BEGIN
BEGIN TRAN
WAITFOR ( RECEIVE TOP(1) @handle = conversation_handle,
@message = message_body
FROM ConstraintQueueReceive), TIMEOUT 1000;
IF @@rowcount = 0
begin
rollback
break;
end
set @sql = N'ALTER TABLE ' + quotename(@message) + N' WITH CHECK CONSTRAINT ALL'
exec (@sql)
if @@error <> 0
begin
rollback tran
break
end
COMMIT TRANSACTION
END
RETURN(0)
GO
现在创建一个过程,为每个表提交一条消息
CREATE PROC p_submit_enable_constraints_message @object sysname
AS
DECLARE @handle UNIQUEIDENTIFIER;
DECLARE @message sysname;
BEGIN TRANSACTION;
BEGIN DIALOG @handle FROM SERVICE [ConstraintServiceSend]
TO SERVICE [ConstraintServiceReceive]
WITH ENCRYPTION = OFF;
SEND ON CONVERSATION @handle (@object);
COMMIT TRANSACTION;
END CONVERSATION @handle
GO
最后,我们可以调用该过程将其提交到队列
EXEC sp_msforeachtable 'EXEC p_submit_enable_constraints_message N''?'''
理想情况下,alter table的结果会被捕获并发送回。感谢您的快速回复。我需要让它回到正常的阶段。我不想把任何事情弄糟。我认为启用需要时间,因为启用时会检查现有数据。我们可以选择禁用数据验证并立即启用吗?@user459295:正如我所说的,更快的选择是用CHECK忽略
,这将产生后果。我不想知道不可信约束的影响。我能够快速运行与检查选项删除。它忽略了数据验证。@user459295:请阅读我在回答中包含的链接中的文章,以了解不受信任的约束的影响。但是,您能告诉我跟踪与表相关的每个约束的方法吗。然后我知道要单独禁用或启用什么。@user459295:约束在sys.foreign\u键中。注意,“名称”列是约束的名称,父对象id是FK所属表的对象id。从那里,您应该能够生成必要的DDL语句。另一种选择是powershell或您最喜欢的SMO工作方式。但那是一匹不同颜色的马。
EXEC sp_msforeachtable 'EXEC p_submit_enable_constraints_message N''?'''