有誰知道一個查詢列出了應用了「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 2008中使用ISNULL到所有列名稱?
- 7. SQL Server:列出查詢中使用的所有列
- 8. 如何在SQL Server中列出所有需要的月份?
- 9. SQL Server查詢列出除主鍵和備用鍵以外的表中的所有列
- 10. MS SQL Server - WITH CHECK在外鍵約束中的值是什麼?
- 11. 如何使用關係列出視圖中的所有列 - SQL Server
- 12. 如何列出SQL Server表的主鍵?
- 13. 如何在SQL Server中使用子選擇插入外鍵
- 14. 在sql server 2008中給外鍵而不是列外鍵
- 15. 在sql server中更新所有外鍵約束?
- 16. 如何使用Powershell列出所有SQL Server表,其列和列數據類型?
- 17. 如何在SQL Buddy中使用外鍵?
- 18. 如何在Sql Server 2000的表中刪除所有外鍵約束?
- 19. 刪除SQL Server中的外鍵和列
- 20. 如何使用T-SQL列出Sql Server 2008上的所有SSIS包
- 21. 在SQL Server中使用With子句
- 22. 如何列出SQL Server中的所有索引視圖?
- 23. 列出所有外鍵PostgreSQL的
- 24. 在SQL Server中創建具有非唯一列的外鍵
- 25. 使用「With Clause」SQL Server 2008
- 26. 如何使用asp.net獲取SQL Server外鍵中的數據?
- 27. 如何使用sql server的存儲過程中的外鍵
- 28. SQL Server的外鍵引用
- 29. SQL Server中的外鍵
- 30. 如何在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