Reputation: 5545
I need to clear many tables (preferably truncate table). But tables have many FK constraints. 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.
Please suggest me how to delete or truncate table by dropping constraints temporarily.
Upvotes: 5
Views: 30500
Reputation: 295
use the following command after deletion of all rows in that table by using delete statement
delete * from tablename
DBCC CHECKIDENT (tablename, RESEED, 0)
Upvotes: 0
Reputation: 15993
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'
Upvotes: 0
Reputation: 103697
just delete them in the proper FK order:
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.
Upvotes: 7
Reputation: 16260
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:
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. 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
Solution 2
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; solution 2 is easier using an external language.
Upvotes: 4
Reputation: 40359
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). 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.
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. Drop all Tables (and, thus, all data). Run script to recreate empty tables.
Upvotes: 0
Reputation: 28875
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. 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. I can strongly recommend Red Gate's SQL compare. 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!
Upvotes: 0
Reputation: 359
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)
Upvotes: 0
Reputation: 1364
Try this:
EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
Upvotes: 0
Reputation: 2648
The easiest (maybe not the fastest) way would be to
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.
Upvotes: 0
Reputation: 8190
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>
Upvotes: 0
Reputation: 25390
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.
So you need drop FK constraints firstly.
Upvotes: 0
Reputation: 11319
The simpliest way to do this is to delete the constraint(s) then reapply them after the truncation.
Upvotes: 0