I want to write sql command to drop all constraints in all tables. I searched on the internet and found the following which works fine if the database is small and not compl
CREATE TABLE #Commands (Command VARCHAR(MAX))
INSERT #Commands
SELECT 'ALTER TABLE ' + QUOTENAME(RC.CONSTRAINT_SCHEMA)
+ '.' + QUOTENAME(KCU1.TABLE_NAME)
+ ' DROP CONSTRAINT ' + QUOTENAME(rc.CONSTRAINT_NAME) + '; '
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU1
ON KCU1.CONSTRAINT_CATALOG = RC.CONSTRAINT_CATALOG
AND KCU1.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA
AND KCU1.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
WHERE ORDINAL_POSITION=1
--SELECT * FROM #Commands
DECLARE @Command VARCHAR(MAX)
DECLARE curCommand CURSOR FOR
SELECT Command FROM #Commands
OPEN curCommand
FETCH NEXT FROM curCommand INTO @Command
WHILE @@FETCH_STATUS =0
BEGIN
EXEC(@Command)
FETCH NEXT FROM curCommand INTO @Command
END
CLOSE curCommand
DEALLOCATE curCommand
DROP TABLE #Commands
I have improved the first script provided by @Yaroslav and the script provided by @Quandary so they now works for databases whose SQL query to drop all foreign keys one by one exceeds the size allocated for the SQL
variable (4000
or MAX
characters).
The altered scripts drop 5
foreign keys per iteration (just to be safe, implemented by adding TOP 5
). The scripts stop when there is no foreign key left to drop (the SQL
variable stays empty after running the SELECT
).
First script by @Yaroslav
DECLARE @SQL varchar(4000)
IterationStart:
SET @SQL=''
SELECT TOP 5 @SQL = @SQL + 'ALTER TABLE ' + FK.TABLE_NAME + ' DROP CONSTRAINT [' + RTRIM(C.CONSTRAINT_NAME) +'];' + CHAR(13)
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK
ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK
ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU
ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME
INNER JOIN (
SELECT i1.TABLE_NAME, i2.COLUMN_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2
ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME
WHERE i1.CONSTRAINT_TYPE = 'PRIMARY KEY'
) PT
ON PT.TABLE_NAME = PK.TABLE_NAME
IF @SQL <> ''
BEGIN
EXEC(@SQL)
GOTO IterationStart
END
Script by @Quandary
DECLARE @sql nvarchar(MAX)
IterationStart:
SET @sql = ''
SELECT TOP 5 @sql = @sql + 'ALTER TABLE ' + QUOTENAME(RC.CONSTRAINT_SCHEMA)
+ '.' + QUOTENAME(KCU1.TABLE_NAME)
+ ' DROP CONSTRAINT ' + QUOTENAME(rc.CONSTRAINT_NAME) + '; '
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU1
ON KCU1.CONSTRAINT_CATALOG = RC.CONSTRAINT_CATALOG
AND KCU1.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA
AND KCU1.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
IF @SQL <> ''
BEGIN
EXEC(@SQL)
GOTO IterationStart
END
Most simple variant:
DECLARE @sql nvarchar(MAX)
SET @sql = N''
SELECT @sql = @sql + N'ALTER TABLE ' + QUOTENAME(KCU1.TABLE_SCHEMA)
+ N'.' + QUOTENAME(KCU1.TABLE_NAME)
+ N' DROP CONSTRAINT ' -- + QUOTENAME(rc.CONSTRAINT_SCHEMA) + N'.' -- not in MS-SQL
+ QUOTENAME(rc.CONSTRAINT_NAME) + N'; ' + CHAR(13) + CHAR(10)
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU1
ON KCU1.CONSTRAINT_CATALOG = RC.CONSTRAINT_CATALOG
AND KCU1.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA
AND KCU1.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
-- PRINT @sql
EXECUTE(@sql)
Here's a short and sweet script I use (on SQL Server 2008 and up) to remove all foreign keys that also takes into account the object's schema:
declare @sql varchar(max) = (
select
'alter table ' + quotename(schema_name(schema_id)) + '.' +
quotename(object_name(parent_object_id)) +
' drop constraint '+quotename(name) + ';'
from sys.foreign_keys
for xml path('')
);
exec sp_executesql @sql;
I used the INFORMATION_SCHEMA solution mentioned by @Yaroslav, but had too many foreign key constants in my database to fit them all into a varchar(MAX). So I had to modify the script to use a temporary table and a cursor instead.
Also, I added []
around the table name.
DECLARE @SQL TABLE (Command VARCHAR(MAX))
INSERT @SQL
SELECT 'ALTER TABLE [' + FK.TABLE_NAME + '] DROP CONSTRAINT [' + RTRIM(C.CONSTRAINT_NAME) +'];' + CHAR(13)
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK
ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK
ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU
ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME
INNER JOIN (
SELECT i1.TABLE_NAME, i2.COLUMN_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2
ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME
WHERE i1.CONSTRAINT_TYPE = 'PRIMARY KEY'
) PT
ON PT.TABLE_NAME = PK.TABLE_NAME
DECLARE cmdCursor CURSOR
FOR SELECT Command FROM @SQL
OPEN cmdCursor
DECLARE @Command VARCHAR(MAX)
FETCH NEXT FROM cmdCursor INTO @Command
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @Command
EXEC (@Command)
FETCH NEXT FROM cmdCursor INTO @Command
END
CLOSE cmdCursor;
DEALLOCATE cmdCursor;
See Pinal's answer from this link, it is very helpful
https://blog.sqlauthority.com/2014/04/11/sql-server-drop-all-the-foreign-key-constraint-in-database-create-all-the-foreign-key-constraint-in-database/
SET NOCOUNT ON
DECLARE @table TABLE(
RowId INT PRIMARY KEY IDENTITY(1, 1),
ForeignKeyConstraintName NVARCHAR(200),
ForeignKeyConstraintTableSchema NVARCHAR(200),
ForeignKeyConstraintTableName NVARCHAR(200),
ForeignKeyConstraintColumnName NVARCHAR(200),
PrimaryKeyConstraintName NVARCHAR(200),
PrimaryKeyConstraintTableSchema NVARCHAR(200),
PrimaryKeyConstraintTableName NVARCHAR(200),
PrimaryKeyConstraintColumnName NVARCHAR(200)
)
INSERT INTO @table(ForeignKeyConstraintName, ForeignKeyConstraintTableSchema, ForeignKeyConstraintTableName, ForeignKeyConstraintColumnName)
SELECT
U.CONSTRAINT_NAME,
U.TABLE_SCHEMA,
U.TABLE_NAME,
U.COLUMN_NAME
FROM
INFORMATION_SCHEMA.KEY_COLUMN_USAGE U
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS C
ON U.CONSTRAINT_NAME = C.CONSTRAINT_NAME
WHERE
C.CONSTRAINT_TYPE = 'FOREIGN KEY'
UPDATE @table SET
PrimaryKeyConstraintName = UNIQUE_CONSTRAINT_NAME
FROM
@table T
INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS R
ON T.ForeignKeyConstraintName = R.CONSTRAINT_NAME
UPDATE @table SET
PrimaryKeyConstraintTableSchema = TABLE_SCHEMA,
PrimaryKeyConstraintTableName = TABLE_NAME
FROM @table T
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS C
ON T.PrimaryKeyConstraintName = C.CONSTRAINT_NAME
UPDATE @table SET
PrimaryKeyConstraintColumnName = COLUMN_NAME
FROM @table T
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE U
ON T.PrimaryKeyConstraintName = U.CONSTRAINT_NAME
--SELECT * FROM @table
--DROP CONSTRAINT:
SELECT
'
ALTER TABLE [' + ForeignKeyConstraintTableSchema + '].[' + ForeignKeyConstraintTableName + ']
DROP CONSTRAINT [' + ForeignKeyConstraintName + ']
GO'
FROM
@table