简体   繁体   English

如何在SQL Server中删除或截断表?

[英]How to delete or truncate table in SQL Server?

I need to clear many tables (preferably truncate table). 我需要清除许多表(最好是截断表)。 But tables have many FK constraints. 但是表有许多FK约束。 I tried something like this, but failed:- 我试过这样的事,但失败了: -

ALTER TABLE Table1 NOCHECK CONSTRAINT ALL 
TRUNCATE TABLE Table1
ALTER TABLE Table1 WITH CHECK CHECK CONSTRAINT ALL

This is the error i am getting:- 这是我得到的错误: -

Cannot truncate table 'Test' because it is being referenced by a FOREIGN KEY constraint. 无法截断表'Test',因为它正被FOREIGN KEY约束引用。

Please suggest me how to delete or truncate table by dropping constraints temporarily. 请通过临时删除约束建议我如何删除或截断表。

just delete them in the proper FK order: 只需按正确的FK顺序删除它们:

DELETE GreatGrandChild
DELETE Child
DELETE Parent

and don't worry about dropping constraints. 并且不用担心放弃约束。

sample code: 示例代码:

create table ParentTable (ParentID int primary key not null, RowValue varchar(10))
INSERT INTO ParentTable VALUES (1,'AAA')
INSERT INTO ParentTable VALUES (2,'BBB')

create table ChildTable (ChildID int primary key not null, ParentID int, RowValue varchar(10))

ALTER TABLE ChildTable ADD CONSTRAINT FK_ChildTable_ParentTable FOREIGN KEY
 (ParentID) REFERENCES dbo.ParentTable (ParentID) ON UPDATE  NO ACTION  ON DELETE  NO ACTION 

INSERT INTO ChildTable VALUES (10,1,'a')
INSERT INTO ChildTable VALUES (11,1,'aa')
INSERT INTO ChildTable VALUES (12,2,'b')
INSERT INTO ChildTable VALUES (13,1,'aaa')

DELETE ChildTable
DELETE ParentTable

to find the tables that depend on your table run this query: 要查找依赖于表的表,请运行此查询:

select 
    object_name(parent_object_id) AS ReferencesYourTable
        ,object_name(referenced_object_id) AS YourTable
        ,* 
    from sys.foreign_keys 
    WHERE object_name(referenced_object_id)='YourTable'

for the above query, delete all the rows in each table listed prior to deleting YourTable. 对于上述查询,删除在删除YourTable之前列出的每个表中的所有行。

Contrary to what others have posted, you can never truncate a table referenced by a foreign key. 与其他人发布的内容相反,您永远不能截断外键引用的表。 It's documented in Books Online under TRUNCATE TABLE, but trying it out yourself is a lot faster: 它在TRUNCATE TABLE下的联机丛书中有记录,但是自己尝试一下要快得多:

create table Parent (col1 int primary key)

create table Child (
    col1 int primary key, 
    col2 int, 
    constraint fk foreign key (col2) references Parent (col1)
)


-- works
truncate table Child
-- doesn't work
truncate table Parent

alter table child nocheck constraint all

-- still doesn't work, even though the FK is disabled
truncate table Parent

drop table Child
drop table Parent

The (conceptual) reason it doesn't work is that TRUNCATE is a physical operation, not a logical one. 它不起作用的(概念)原因是TRUNCATE是物理操作,而不是逻辑操作。 So it is not 'foreign key aware' and if you let it ignore foreign keys it would kill referential integrity. 所以它不是'外键识别',如果你让它忽略外键,它会杀死参照完整性。

The usual solutions (as mentioned by others) are: 通常的解决方案(如其他人所述)是:

Solution 1 解决方案1

  1. Drop foreign keys 删除外键
  2. Truncate tables 截断表格
  3. Re-create foreign keys 重新创建外键

Solution 2 解决方案2

  1. Drop tables 删除表
  2. Re-create tables 重新创建表

Either solution works, it's really a deployment issue as to which is easier and suits your situation better. 无论哪种解决方案都有效,它确实是一个部署问题,因为它更容易,更适合您的情况。 I know you said it's a one-time task, but I would still script it, even if only as a learning experience. 我知道你说这是一次性任务,但我仍然会编写脚本,即使只是作为一种学习经历。 Solution 1 is easy in pure TSQL; 解决方案1在纯TSQL中很容易; solution 2 is easier using an external language. 解决方案2使用外部语言更容易。

use the following command after deletion of all rows in that table by using delete statement 使用delete语句删除该表中的所有行后,使用以下命令

delete * from tablename 从表名中删除*

DBCC CHECKIDENT (tablename, RESEED, 0) DBCC CHECKIDENT(tablename,RESEED,0)

最简单的方法是删除约束,然后在截断后重新应用它们。

You need also drop constraints in all your tables which referenced to your truncated table. 您还需要在所有引用截断表的表中删除约束。 After that you will be able truncate table. 之后,您将能够截断表格。 But do not forget create them again. 但不要忘记再次创建它们。

Also MSSQL does not allow truncate table even if all tables referenced to your truncated table have not rows. 即使引用截断表的所有表都没有行,MSSQL也不允许截断表。

So you need drop FK constraints firstly. 所以你需要首先删除FK约束。

What you need to do (and there may be a tool, but I don't know of one) is dissable ALL of your relationships which attach to your affected tables (both to and from the table being truncated). 您需要做什么(并且可能有一个工具,但我不知道一个)是不可用的所有关系附加到受影响的表(来自和被截断的表)。 That often means disabling constraints on other tables. 这通常意味着禁用其他表的约束。

<SoapBox> I'm sure you're aware of this, but I'd be remiss if I didn't point out that those constraints probably exist for a very good reason, and you need to be very, very sure that your data is clean both before and after your truncate. <SoapBox>我确定你已经意识到了这一点,但如果我没有指出这些约束可能存在的原因非常充分,那么我就会失职,你需要非常非常确定你的数据在截断之前和之后都是干净的。 <\\SoapBox>

The easiest (maybe not the fastest) way would be to DELETE FROM Table1 . 最简单(也许不是最快)的方法是DELETE FROM Table1

That does work even wit foreign keys (however, the order of deletes should take into account to delete tables with foreign keys before tables with the matching primary keys. 即使是外键也能正常工作(但是,删除顺序应该考虑在具有匹配主键的表之前删除具有外键的表。

试试这个:

EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"

You would need to delete or truncate any table with a foreign key to Table1 or perform a cascading delete if your database supports it (I think it was added in SQL Server 2005) 您需要使用Table1的外键删除或截断任何表,或者如果您的数据库支持它,则执行级联删除(我认为它是在SQL Server 2005中添加的)

Sql Server Cascading Delete Sql Server级联删除

If you need to make significant changes to your database structure you have three choices. 如果需要对数据库结构进行重大更改,则有三种选择。 First, you can work through all of the constraints, dropping and then recreating them in scripts around the core action that you'll take. 首先,您可以处理所有约束,删除然后在围绕您将采取的核心操作的脚本中重新创建它们。 This is fairly time intensive and error prone. 这是相当耗时且容易出错的。 These second option is to find a way to perform the action using the "Design" capability in Enterprise Studio. 第二个选项是使用Enterprise Studio中的“设计”功能找到执行操作的方法。 However, before saving the action just right-click in the design window and ask to save as a script. 但是,在保存操作之前,只需右键单击设计窗口并要求保存为脚本。 This will give you a starting point if you have fine-tuning you wish to do in the script. 如果您希望在脚本中进行微调,这将为您提供一个起点。

Your final option - and the one that I prefer - is to use a third-party DDL generator to make your database structure changes. 您的最终选项 - 以及我更喜欢的选项 - 是使用第三方DDL生成器来更改数据库结构。 I can strongly recommend Red Gate's SQL compare. 我强烈推荐Red Gate的SQL比较。 It too will generate a script but it makes it easy to compare two databases to discover how to transform one to the other. 它也会生成一个脚本,但它可以很容易地比较两个数据库,以发现如何将一个数据库转换为另一个数据库。 Good luck! 祝好运!

I did something this in an ETL system by "logging" each foreign key in a user table along with CREATE and DROP scripts (all based on ALTER TABLE, of course). 我在ETL系统中做了一些事情,通过“记录”用户表中的每个外键以及CREATE和DROP脚本(当然,所有这些都基于ALTER TABLE)。 For your situation, you'd loop through it in specified order and, for each table, extract and execute all the "drop key" scripts, truncate the table, then apply the "create key" scripts. 根据您的情况,您将按指定的顺序循环访问它,并为每个表提取并执行所有“drop key”脚本,截断表,然后应用“create key”脚本。

Doesn't really help for a one-time run. 对一次性运行没有帮助。 It requires development and serious debugging (because it has to work). 它需要开发和认真调试(因为它必须工作)。 And each time you modify your architecture you may have to update the contents of this table. 每次修改架构时,都可能需要更新此表的内容。 But if you do this process as part of your regular procedures, it'll be worth the effort. 但是,如果您将此过程作为常规程序的一部分,那么值得付出努力。

Option 2: Generate "create" script via SSMS of all target tables. 选项2:通过所有目标表的SSMS生成“创建”脚本。 Drop all Tables (and, thus, all data). 删除所有表(以及所有数据)。 Run script to recreate empty tables. 运行脚本以重新创建空表。

Also try this. 也试试这个。

Uncheck constraints temporarily and then recheck. 暂时取消选中约束,然后重新检查。

EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'    
EXEC sp_MSForEachTable 'ALTER TABLE ? DISABLE TRIGGER ALL'    
EXEC sp_MSForEachTable 'DELETE FROM ?'   
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'    
EXEC sp_MSForEachTable 'ALTER TABLE ? ENABLE TRIGGER ALL'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM