我试图删除数据库中的所有表,而不必按正确的顺序执行。从我所看到的运行NOCHECK命令将阻止检查外键。但是,即使在运行之后我仍然会在尝试删除第一个表时出错。
无法删除对象' dbo.TABLENAME'因为它被引用 FOREIGN KEY约束
我之前已经看到这个问题得到了成功解答,所以我不明白与我在做什么有什么不同。这是在SQL Server 2008 R2上运行。
BEGIN TRANSACTION
--get current list of tables
SELECT QUOTENAME(s.NAME) + '.' + QUOTENAME(t.NAME) as 'Dropped Table'
FROM sys.tables t
JOIN sys.schemas s
ON t.[schema_id] = s.[schema_id]
WHERE t.type = 'U'
--disable constraint checking in all tables
DECLARE @sql NVARCHAR(max)
SET @sql = ''
SELECT @sql += ' ALTER TABLE ' + QUOTENAME(s.NAME) + '.' + QUOTENAME(t.NAME) + ' NOCHECK CONSTRAINT ALL; '
FROM sys.tables t
JOIN sys.schemas s
ON t.[schema_id] = s.[schema_id]
WHERE t.type = 'U'
select @sql
Exec sp_executesql @sql
--disable all constraints (this also didn't work)
--EXEC sp_MSforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
--drop all tables
SET @sql = ''
SELECT @sql += ' DROP TABLE ' + QUOTENAME(s.NAME) + '.' + QUOTENAME(t.NAME) + '; '
FROM sys.tables t
JOIN sys.schemas s
ON t.[schema_id] = s.[schema_id]
WHERE t.type = 'U'
select @sql
Exec sp_executesql @sql
--check current list, should be empty
SELECT QUOTENAME(s.NAME) + '.' + QUOTENAME(t.NAME) as 'Tables'
FROM sys.tables t
JOIN sys.schemas s
ON t.[schema_id] = s.[schema_id]
WHERE t.type = 'U'
ROLLBACK TRANSACTION
更新1
我删除了约束禁用代码来代替约束丢弃代码,但是它给出了错误。
--drop all constraints
DECLARE @sql NVARCHAR(max)
SET @sql = ''
SELECT @sql += ' ALTER TABLE ' +QUOTENAME(s.NAME) + '.' + QUOTENAME(t.NAME) + ' DROP CONSTRAINT ' + ctu.CONSTRAINT_NAME + ';'
FROM sys.tables t
JOIN sys.schemas s
ON t.[schema_id] = s.[schema_id]
INNER JOIN EOS_DEV.INFORMATION_SCHEMA.CONSTRAINT_TABLE_USAGE as ctu
ON ctu.TABLE_SCHEMA = s.name AND ctu.TABLE_NAME = t.name
WHERE t.type = 'U'
Exec sp_executesql @sql
约束' [CONSTRAINT_NAME]'正在被表引用 ' [TABLE_NAME]',外键约束' [FK_NAME]'
如何修改此查询,以便仅针对FK约束?
答案 0 :(得分:0)
将FK设置为NOCHECK将允许您INSERT,UPDATE或DELETE违反约束的行。它不允许您DROP或TRUNCATE目标表。 EG:
use tempdb
create table a(id int primary key)
create table b(id int primary key, aid int references a)
alter table b nocheck constraint all
insert into b(id,aid) values (1,1) --succeeds because of nocheck
drop table a --fails
--Msg 3726, Level 16, State 1, Line 11
--Could not drop object 'a' because it is referenced by a FOREIGN KEY constraint.
答案 1 :(得分:0)
你必须这么难吗?为什么不只是还原一个空数据库(或只包含您的架构的数据库以及需要什么“默认”行)?
答案 2 :(得分:0)
感谢大家的帮助。我更新了我的查询,现在可以确认它能够不加选择地删除所有表。我还添加了一个部分来删除所有存储过程以获得一些额外的味道。
BEGIN TRANSACTION
--get current list of tables
SELECT QUOTENAME(s.NAME) + '.' + QUOTENAME(t.NAME) as 'Dropped Table'
FROM sys.tables t
JOIN sys.schemas s
ON t.[schema_id] = s.[schema_id]
WHERE t.type = 'U'
--drop all constraints
DECLARE @sql NVARCHAR(max)
SET @sql = ''
SELECT @sql += ' ALTER TABLE ' +QUOTENAME(s.NAME) + '.' + QUOTENAME(t.NAME) + ' DROP CONSTRAINT ' + tc.CONSTRAINT_NAME + ';'
FROM sys.tables t
JOIN sys.schemas s
ON t.[schema_id] = s.[schema_id]
INNER JOIN EOS_DEV.INFORMATION_SCHEMA.TABLE_CONSTRAINTS as tc
ON tc.TABLE_SCHEMA = s.name AND tc.TABLE_NAME = t.name
WHERE t.type = 'U'
AND tc.CONSTRAINT_TYPE = 'FOREIGN KEY'
Exec sp_executesql @sql
--drop all tables
SET @sql = ''
SELECT @sql += ' DROP TABLE ' + QUOTENAME(s.NAME) + '.' + QUOTENAME(t.NAME) + '; '
FROM sys.tables t
JOIN sys.schemas s
ON t.[schema_id] = s.[schema_id]
WHERE t.type = 'U'
Exec sp_executesql @sql
--drop all stored procs
SET @sql = ''
SELECT @sql += 'DROP PROCEDURE [' + SCHEMA_NAME(p.schema_id) + '].[' + p.NAME + ']'
FROM sys.procedures as p
where p.is_ms_shipped = 0
AND p.type = 'P'
Exec sp_executesql @sql
ROLLBACK TRANSACTION