Disabling foreign key constraint, still can't truncate table? (SQL Server 2005)
I have a table called PX_Child that has a foreign key on PX_Parent. I'd like to temporarily disable this FK constraint so that I can truncate PX_Parent. I'm not sure how this goes however.
I've 开发者_JS百科tried these commands
ALTER TABLE PX_Child NOCHECK CONSTRAINT ALL
ALTER TABLE PX_Parent NOCHECK CONSTRAINT ALL
(truncate commands)
ALTER TABLE PX_Child CHECK CONSTRAINT ALL
ALTER TABLE PX_Parent CHECK CONSTRAINT ALL
But the truncate still tells me it can't truncate PX_Parent because of a foreign key constraint. I've looked all around the net and can't seem to find what I'm doing wrong, sorry for the basic nature of this question.
You can't truncate the table if there is any foreign key referencing it, including disabled constraints. You either need to drop the foreign key constraints or use the DELETE
command.
There is an easier-ish way. I was faced with the same problem and found this solution: https://www.mssqltips.com/sqlservertip/3347/drop-and-recreate-all-foreign-key-constraints-in-sql-server/
If you just run this query in your DB, it will generate the T-SQL you need to include before/after your sproc, in order to delete and then restore any foreign key constraints.
Don't worry about trying to understand this query itself.
CREATE TABLE #x -- feel free to use a permanent table
(
drop_script NVARCHAR(MAX),
create_script NVARCHAR(MAX)
);
DECLARE @drop NVARCHAR(MAX) = N'',
@create NVARCHAR(MAX) = N'';
-- drop is easy, just build a simple concatenated list from sys.foreign_keys:
SELECT @drop += N'
ALTER TABLE ' + QUOTENAME(cs.name) + '.' + QUOTENAME(ct.name)
+ ' DROP CONSTRAINT ' + QUOTENAME(fk.name) + ';'
FROM sys.foreign_keys AS fk
INNER JOIN sys.tables AS ct
ON fk.parent_object_id = ct.[object_id]
INNER JOIN sys.schemas AS cs
ON ct.[schema_id] = cs.[schema_id];
INSERT #x(drop_script) SELECT @drop;
-- create is a little more complex. We need to generate the list of
-- columns on both sides of the constraint, even though in most cases
-- there is only one column.
SELECT @create += N'
ALTER TABLE '
+ QUOTENAME(cs.name) + '.' + QUOTENAME(ct.name)
+ ' ADD CONSTRAINT ' + QUOTENAME(fk.name)
+ ' FOREIGN KEY (' + STUFF((SELECT ',' + QUOTENAME(c.name)
-- get all the columns in the constraint table
FROM sys.columns AS c
INNER JOIN sys.foreign_key_columns AS fkc
ON fkc.parent_column_id = c.column_id
AND fkc.parent_object_id = c.[object_id]
WHERE fkc.constraint_object_id = fk.[object_id]
ORDER BY fkc.constraint_column_id
FOR XML PATH(N''), TYPE).value(N'.[1]', N'nvarchar(max)'), 1, 1, N'')
+ ') REFERENCES ' + QUOTENAME(rs.name) + '.' + QUOTENAME(rt.name)
+ '(' + STUFF((SELECT ',' + QUOTENAME(c.name)
-- get all the referenced columns
FROM sys.columns AS c
INNER JOIN sys.foreign_key_columns AS fkc
ON fkc.referenced_column_id = c.column_id
AND fkc.referenced_object_id = c.[object_id]
WHERE fkc.constraint_object_id = fk.[object_id]
ORDER BY fkc.constraint_column_id
FOR XML PATH(N''), TYPE).value(N'.[1]', N'nvarchar(max)'), 1, 1, N'') + ');'
FROM sys.foreign_keys AS fk
INNER JOIN sys.tables AS rt -- referenced table
ON fk.referenced_object_id = rt.[object_id]
INNER JOIN sys.schemas AS rs
ON rt.[schema_id] = rs.[schema_id]
INNER JOIN sys.tables AS ct -- constraint table
ON fk.parent_object_id = ct.[object_id]
INNER JOIN sys.schemas AS cs
ON ct.[schema_id] = cs.[schema_id]
WHERE rt.is_ms_shipped = 0 AND ct.is_ms_shipped = 0;
UPDATE #x SET create_script = @create;
PRINT @drop;
PRINT @create;
/*
EXEC sp_executesql @drop
-- clear out data etc. here
EXEC sp_executesql @create;
*/
Generates a bunch of:
ALTER TABLE [dbo].[Whatever] DROP CONSTRAINT....
--
ALTER TABLE [dbo].[Whatever] ADD CONSTRAINT....
SQL server will not let you truncate the table while the constraint exists, even if it's disabled. Drop the constraint and re-create it after truncating the table. Or just drop and re-create the tables, whichever is easier to do in your application.
There is no such option to truncate table while foreign key constraint but we can use some trick like
ALTER TABLE [dbo].[table2] DROP CONSTRAINT [FK_table2_table1]
GO
truncate table [table1]
GO
ALTER TABLE [dbo].[table2] WITH CHECK ADD CONSTRAINT [FK_table2_table1] FOREIGN KEY([FKId])
REFERENCES [dbo].[table1] ([ID])
GO
ALTER TABLE [dbo].[table2] CHECK CONSTRAINT [FK_table2_table1]
GO
精彩评论