views:

216

answers:

10

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.

A: 

The simpliest way to do this is to delete the constraint(s) then reapply them after the truncation.

Achilles
A: 

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.

Michael Pakhantsov
A: 

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>

AllenG
A: 

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.

Frank
+2  A: 

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.

KM
is there any way to find which table is child of which? (other than manually)
Novice
look at the error message, the FK indicates the table that needs to truncated before the current one, use this query to find any tables that need to be deleted before YourTable: `select object_name(parent_object_id),object_name(referenced_object_id),* from sys.foreign_keys WHERE object_name(referenced_object_id)='YoutTable'`
KM
It doesn't matter what order you truncate in, or even if the tables are empty, you can never truncate a table referenced by foreign key (unless it's a self-referencing FK).
Pondlife
I agree with @Pondlife. You can't truncate a table that is referenced by a foreign key.
bobs
KM
KM, see TRUNCATE TABLE in Books Online. Better still, don't take my word for it, just test it yourself and see. You can copy and paste code from my answer on this page.(Posted seconds after KM's update)
Pondlife
A: 

Try this:

EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
Vidar Nordnes
didn't help me?
Novice
A: 

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)

Sql Server Cascading Delete

kniemczak
A: 

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!

Mark Brittingham
A: 

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.

Philip Kelley
A: 

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

  1. Drop foreign keys
  2. Truncate tables
  3. Re-create foreign keys

Solution 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; solution 2 is easier using an external language.

Pondlife