有谁知道一个查询列出了应用了“WITH NOCHECK”说明的数据库中的所有外键吗? (去除它们将提高性能和稳定性)。如何在SQL Server中使用“WITH NOCHECK”列出所有外键
回答
下面将在目前的返回外键的名称数据库与NOCHECK
残疾人即对于SQL Server 2005/2008:
select * from sys.foreign_keys where is_disabled=1
有大约不受信任禁用&之间的差别,答案了一些讨论。 以下内容解释了差异 下面是一些代码,用于说明is_disabled &之间的区别是不可信的。
-- drop table t1
-- drop table t2
create table t1(i int not null, fk int not null)
create table t2(i int not null)
-- create primary key on t2
alter table t2
add constraint pk_1 primary key (i)
-- create foriegn key on t1
alter table t1
add constraint fk_1 foreign key (fk)
references t2 (i)
--insert some records
insert t2 values(100)
insert t2 values(200)
insert t2 values(300)
insert t2 values(400)
insert t2 values(500)
insert t1 values(1,100)
insert t1 values(2,100)
insert t1 values(3,500)
insert t1 values(4,500)
----------------------------
-- 1. enabled and trusted
select name,is_disabled,is_not_trusted from sys.foreign_keys
GO
-- 2. disable the constraint
alter table t1 NOCHECK CONSTRAINT fk_1
select name,is_disabled,is_not_trusted from sys.foreign_keys
GO
-- 3. re-enable constraint, data isnt checked, so not trusted.
-- this means the optimizer will still have to check the column
alter table t1 CHECK CONSTRAINT fk_1
select name,is_disabled,is_not_trusted from sys.foreign_keys
GO
--4. drop the foreign key constraint & re-add
-- it making sure its checked
-- constraint is then enabled and trusted
alter table t1 DROP CONSTRAINT fk_1
alter table t1 WITH CHECK
add constraint fk_1 foreign key (fk)
references t2 (i)
select name,is_disabled,is_not_trusted from sys.foreign_keys
GO
--5. drop the foreign key constraint & add but dont check
-- constraint is then enabled, but not trusted
alter table t1 DROP CONSTRAINT fk_1
alter table t1 WITH NOCHECK
add constraint fk_1 foreign key (fk)
references t2 (i)
select name,is_disabled,is_not_trusted from sys.foreign_keys
GO
is_disabled
手段约束被禁用
isnottrusted
意味着SQL Server不相信,列已针对外键表检查。
因此不能假定重新启用外键约束将被优化。为确保优化器信任该列,最好放弃外键约束&使用WITH CHECK
选项(4.)
WITH NOCHECK应该只适用于FK的暂时性,或者当您的链接文章指出它们对优化程序无用时。从BOL:
的查询优化器不会考虑与 NOCHECK定义 约束。这些约束将被忽略 ,直到通过使用 重新启用它们为止。ALTER TABLE表CHECK CONSTRAINT ALL。
这会找出所有的外键(在WITH NOCHECK位工作...)
SELECT C.TABLE_CATALOG [PKTABLE_QUALIFIER],
C.TABLE_SCHEMA [PKTABLE_OWNER],
C.TABLE_NAME [PKTABLE_NAME],
KCU.COLUMN_NAME [PKCOLUMN_NAME],
C2.TABLE_CATALOG [FKTABLE_QUALIFIER],
C2.TABLE_SCHEMA [FKTABLE_OWNER],
C2.TABLE_NAME [FKTABLE_NAME],
KCU2.COLUMN_NAME [FKCOLUMN_NAME],
RC.UPDATE_RULE,
RC.DELETE_RULE,
C.CONSTRAINT_NAME [FK_NAME],
C2.CONSTRAINT_NAME [PK_NAME],
CAST(7 AS SMALLINT) [DEFERRABILITY]
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS C
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU
ON C.CONSTRAINT_SCHEMA = KCU.CONSTRAINT_SCHEMA
AND C.CONSTRAINT_NAME = KCU.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC
ON C.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA
AND C.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS C2
ON RC.UNIQUE_CONSTRAINT_SCHEMA = C2.CONSTRAINT_SCHEMA
AND RC.UNIQUE_CONSTRAINT_NAME = C2.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU2
ON C2.CONSTRAINT_SCHEMA = KCU2.CONSTRAINT_SCHEMA
AND C2.CONSTRAINT_NAME = KCU2.CONSTRAINT_NAME
AND KCU.ORDINAL_POSITION = KCU2.ORDINAL_POSITION
WHERE C.CONSTRAINT_TYPE = 'FOREIGN KEY'
Ref。
顺便说一句,这两个SQL Server 2000和2005年,但如果任何数据违反使用约束检查:
DBCC CHECKCONSTRAINTS (table_name)
DBCC CHECKCONSTRAINTS很有用,但这实际上并没有回答这个问题。 – digiguru 2009-08-10 09:27:13
SELECT * FROM sys.foreign_keys AS f Where Is_Not_Trusted = 1
is_not_trusted列表示sql server没有*检查*值以确保FK的完整性。即如果约束曾应用NOCHECK!这非常聪明,实际上优化器会用来确定它是否可以信任列的完整性。所以你需要做的是不重新启用约束,但重新检查列 – 2009-08-10 09:59:43
但它不是“禁用”。你会如何建议执行“重新启用”它? – digiguru 2009-08-10 10:24:48
+1:digiguru,http://msdn.microsoft.com/en-us/library/ms189807.aspx您可以像这样重新检查密钥:'ALTER TABLE [schema]。[table] CHECK CONSTRAINT [FK_myConstraint] ' – Brad 2010-10-29 19:57:15
重新创建它以下代码将检索标记为'WITH NOCHECK'的所有外键,然后使用ALTER语句来解决这些问题了:
-- configure cursor on all FKs with "WITH NOCHECK"
DECLARE UntrustedForeignKeysCursor CURSOR STATIC FOR
SELECT f.name,
t.name
FROM sys.foreign_keys AS f
LEFT JOIN sys.tables AS t
ON f.parent_object_id = t.object_id
Where Is_Not_Trusted = 1
OPEN UntrustedForeignKeysCursor
-- loop through the untrusted FKs
DECLARE @FKName varchar(100)
DECLARE @TableName varchar(100)
FETCH NEXT FROM UntrustedForeignKeysCursor INTO @FKName, @TableName
WHILE @@FETCH_STATUS = 0
BEGIN
-- Rebuild the FK constraint WITH CHECK
EXEC ('ALTER TABLE ' + @TableName + ' WITH CHECK CHECK CONSTRAINT ' + @FKName)
-- get next user
FETCH NEXT FROM UntrustedForeignKeysCursor INTO @FKName, @TableName
END
-- cleanup
CLOSE UntrustedForeignKeysCursor
下面的脚本将生成ALTER语句都将检查现有数据,并防止对那些目前没有可信的(“WITH NOCHECK”)外键的任何新的违规行为。
在SQL Server Management Studio中执行它以生成脚本,然后将它们复制到查询窗口中以执行它们。
select
'alter table ' + quotename(s.name) + '.' + quotename(t.name) + ' with check check constraint ' + fk.name +';'
from
sys.foreign_keys fk
inner join
sys.tables t
on
fk.parent_object_id = t.object_id
inner join
sys.schemas s
on
t.schema_id = s.schema_id
where
fk.is_not_trusted = 1
我知道这是一个老问题,有一些老的答案有一些很好的信息。不过,我只是想分享,我一直在使用相当多的不同的数据库来解决这一问题方面为我们的脚本:
-- Foreign Keys
SELECT 'ALTER TABLE ' + o.name + ' WITH CHECK CHECK CONSTRAINT ' + i.name + ';' AS AlterStatement
from sys.foreign_keys i
INNER JOIN sys.objects o ON i.parent_object_id = o.object_id
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
WHERE i.is_not_trusted = 1 AND i.is_not_for_replication = 0;
GO
-- Constraints
SELECT 'ALTER TABLE ' + o.name + ' WITH CHECK CHECK CONSTRAINT ' + i.name + ';' AS AlterStatement
from sys.check_constraints i
INNER JOIN sys.objects o ON i.parent_object_id = o.object_id
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
WHERE i.is_not_trusted = 1 AND i.is_not_for_replication = 0 AND i.is_disabled = 0;
GO
,这将产生ALTER语句的集合,以解决这个问题“NOCHECK”问题与外键和约束。这是基于Brent Ozar提供的一些查询,但是我为了我的目的和易用性而进行了调整。这可以很容易地调整与UNION
使其成为一个单一的查询。
仅供参考,我在Azure SQL数据库环境中专门使用了它。我不确定在旧版本的SQL Server上是否存在限制,但它在Azure中效果很好。
- 1. 如何使用T-SQL列出SQL Server中的所有表名?
- 2. 如何在SQL Server中的外键添加到现有列2012
- 3. 如何在SQL Server中使用不同列表的所有列
- 4. 如何在SQL Server中删除外键?
- 5. sql列出了主键的所有外键
- 6. 如何在SQL Server中列出所有需要的月份?
- 7. 如何列出SQL Server表的主键?
- 8. 如何在SQL Server中使用子选择插入外键
- 9. 如何使用Powershell列出所有SQL Server表,其列和列数据类型?
- 10. 如何在SQL Buddy中使用外键?
- 11. 如何在Sql Server 2000的表中删除所有外键约束?
- 12. 删除SQL Server中的外键和列
- 13. 如何使用T-SQL列出Sql Server 2008上的所有SSIS包
- 14. 在SQL Server中使用With子句
- 15. 如何列出SQL Server中的所有索引视图?
- 16. 列出所有外键PostgreSQL的
- 17. 在SQL Server中创建具有非唯一列的外键
- 18. 使用“With Clause”SQL Server 2008
- 19. 如何使用asp.net获取SQL Server外键中的数据?
- 20. SQL Server的外键引用
- 21. SQL Server中的外键
- 22. SQL Server中的所有关键字
- 23. SQL Server主键/外键
- 24. 在SQL Server中有“WITH SCHEMABINDING”的缺点?
- 25. SQL Server使用外键创建表
- 26. 使用VS2010 SQL Server数据库项目在SQL脚本中获取'WITH CHECK'输出?
- 27. 如何使用Squirrel SQL列出数据库中的所有表?
- 28. SQL Server,查找外键列的总和
- 29. SQL Server列表外键信息
- 30. SQL请求列出Sql-Server实例中的所有数据库?
什么版本的SQL Server? – 2009-08-10 08:42:36
SQL Server 2005 – digiguru 2009-08-10 08:50:07
伙计们,我需要同样的东西,但SQL 2000兼容! – 2010-05-19 22:48:43