Drop primary key using script in SQL Server database [duplicate] - sql-server

This question already has answers here:
Finding a Primary Key Constraint on the fly in SQL Server 2005
(4 answers)
Closed 5 years ago.
I need to drop the primary key of a table Student in a SQL Server database.
I have edited in the table and the script I got is
ALTER TABLE dbo.Student
DROP CONSTRAINT PK__Student__9CC368536561EF8B
But when I run this script in SQL Server query browser to drop the primary key
It shows the message
Msg 3728, Level 16, State 1, Line 1
'PK__Student__9CC368536561EF8B' is not a constraint.
Msg 3727, Level 16, State 0, Line 1
To my concern I think PK__Student__9CC368536561EF8B this will be generated randomly
please help me to drop the primary key constraint using script.
Thanks in advance

You can look up the constraint name in the sys.key_constraints table:
SELECT name
FROM sys.key_constraints
WHERE [type] = 'PK'
AND [parent_object_id] = Object_id('dbo.Student');
If you don't care about the name, but simply want to drop it, you can use a combination of this and dynamic sql:
DECLARE #table NVARCHAR(512), #sql NVARCHAR(MAX);
SELECT #table = N'dbo.Student';
SELECT #sql = 'ALTER TABLE ' + #table
+ ' DROP CONSTRAINT ' + name + ';'
FROM sys.key_constraints
WHERE [type] = 'PK'
AND [parent_object_id] = OBJECT_ID(#table);
EXEC sp_executeSQL #sql;
This code is from Aaron Bertrand (source).

simply click
'Database'>tables>your table name>keys>copy the constraints like 'PK__TableName__30242045'
and run the below query is :
Query:alter Table 'TableName' drop constraint PK__TableName__30242045

The answer I got is that variables and subqueries
will not work and we have to user dynamic SQL script. The following works:
DECLARE #SQL VARCHAR(4000)
SET #SQL = 'ALTER TABLE dbo.Student DROP CONSTRAINT |ConstraintName| '
SET #SQL = REPLACE(#SQL, '|ConstraintName|', ( SELECT name
FROM sysobjects
WHERE xtype = 'PK'
AND parent_obj = OBJECT_ID('Student')))
EXEC (#SQL)

Related

How to detect if a table is a FileTable in SQL Server

I am working with an existing SQL script which drops all foreign keys from a database. This runs into trouble if one of the tables is a FileTable.
The primary question: is there a way to detect that a particular table is a FILETABLE and skip dropping the foreign keys on that table?
If that is possible: is it also possible to get even more granular and drop any non-system generated foreign keys from the FILETABLE by differentiating between system foreign keys and custom foreign keys?
DECLARE #fkdel varchar(512);
DECLARE FkCrsr CURSOR FOR
SELECT 'ALTER TABLE [' + TABLE_SCHEMA + '].[' + TABLE_NAME + '] DROP CONSTRAINT [' + CONSTRAINT_NAME +']'
FROM information_schema.table_constraints WITH (NOLOCK)
WHERE CONSTRAINT_TYPE = 'FOREIGN KEY';
OPEN FkCrsr;
FETCH NEXT FROM FkCrsr INTO #fkdel;
WHILE ##FETCH_STATUS = 0
BEGIN;
PRINT #fkdel;
EXEC (#fkdel);
FETCH NEXT FROM FkCrsr INTO #fkdel;
END;
CLOSE FkCrsr;
DEALLOCATE FkCrsr;
EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all";
Running this on a database containing a FileTable results in an error like
Msg 3865, Level 16, State 1, Line 3
The operation on object 'FK__DocumentS__paren__3A69DAC6' is blocked. The object is a FileTable system defined object and user modifications are not allowed.
Msg 3727, Level 16, State 0, Line 3
Could not drop constraint. See previous errors.
You should not be using the information schema views for this. Especially since you care about the schema. The MS documentation even states not to use this. https://learn.microsoft.com/en-us/sql/relational-databases/system-information-schema-views/table-constraints-transact-sql?view=sql-server-ver15
If you instead use the system views this becomes a lot simpler. For example sys.tables has a column "is_filetable". https://learn.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-tables-transact-sql?view=sql-server-ver15 Also notice I am using QUOTENAME here instead of manually adding square brackets.
Then you can query sys.foreign_keys to find all your foreign keys since that is the only type of constraint you are concerned with.
Your whole looping construct could be simplified to something like this.
declare #SQL nvarchar(max) = ''
select #SQL = #SQL + 'ALTER TABLE ' + QUOTENAME(s.name) + '.' + QUOTENAME(t.name) + ' DROP CONSTRAINT ' + QUOTENAME(fk.name) + ';'
from sys.foreign_keys fk
join sys.tables t on t.object_id = fk.parent_object_id
join sys.schemas s on s.schema_id = t.schema_id
where t.is_filetable = 0
select #SQL
--uncomment the line below to execute your dynamic sql
--exec sp_executesql #SQL
That takes us to sp_msforeachtable. It is rarely a good idea to use undocumented procedures like this. I would also be a bit nervous that you are turning off every constraint on every table instead of just the ones you removed. Maybe instead you should capture all the tables you are going to drop foreign keys from (before you drop them) and then disable all the constraints on ONLY those tables.

SQL Server - Foreign key creation to multiple tables

I have a requirement where I need to create a foreign key for more than 200 tables. Ex, there is emp table which has ID has primary key, now the 200 tables have emp_id, which I need to reference to emp.id.
I know I can write 200 alter statements to create the foreign key. Is there an easier way to create with one simple script?
Please advise. Thanks for your help.
Here is a trick to do it
DECLARE #sql NVARCHAR(max)=''
SELECT #sql += '
ALTER TABLE ' + Object_name(object_id)
+ '
ADD CONSTRAINT FK_'
+ Object_name(object_id)
+ '_EMP_emp_id FOREIGN KEY (emp_id) REFERENCES EMP(id);'
FROM sys.COLUMNS
WHERE NAME = 'emp_id'
--Print #sql
EXEC Sp_executesql
#sql
Note :
Print #SQL variable and check the generated SQL is good
Above code consider's all the 200 table has the same name 'emp_id' to which foreign key is created
This may fail when the 'emp_id' column has bad data (ie) a 'emp_id' which is not present in EMP table
You could probably generate the alter table statements dynamically using information_schema.columns. Something like this should get you started:
SELECT 'ALTER TABLE '+ TABLE_NAME +
' ADD CONSTRAINT FK_'+ TABLE_NAME +'_Emp FOREIGN KEY ('+ COLUMN_NAME +')'+
' REFERENCES emp (Id)'+
' ON DELETE CASCADE'+
' ON UPDATE CASCADE;'+
' GO '
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME = 'emp_id'

Truncate Table With Foreign Key

I have one database having above 1000+ tables. I am creating fresh Blank setup. For that i have to truncate all the tables but some of the tables i do not wish to truncate so i created on table and stored the names in the table.
----------- Create hardcode table ----------------------
Create table TblHardCodeTableNotToTruncate(TableName varchar(100))
go
insert into TblHardCodeTableNotToTruncate
select 'TblHardCodeTableNotToTruncate'
go
---- insert the table names which dont wish to truncate ------------
Insert into TblHardCodeTableNotToTruncate
select 'TblAccount'
go
Insert into TblHardCodeTableNotToTruncate
select 'TblCity'
go
etc, Following is the query i used to truncate all the tables except these inserted tables
------------------------- Truncate all the tables except the tables specified in the Hardcode table -------------------------
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
GO
EXEC sp_MSForEachTable 'ALTER TABLE ? DISABLE TRIGGER ALL'
GO
DECLARE #TBLTEMP TABLE(TABLENAME VARCHAR(100))
insert into #TBLTEMP
select name from sysobjects where xtype = 'U'
delete from #TBLTEMP where tablename in (
select tablename from TblHardCodeTableNotToTruncate)
DECLARE #SQLQUERY VARCHAR(MAX) =''
DECLARE #INTCNT INT = 1
DECLARE #TABLENAME VARCHAR(100) =''
WHILE (SELECT COUNT(*) FROM #TBLTEMP) > 0
BEGIN
select top 1 #TABLENAME = TABLENAME from #TBLTEMP
SET #SQLQUERY = 'Truncate table ' + #TABLENAME
EXEC(#SQLQUERY)
PRINT #SQLQUERY
DELETE FROM #TBLTEMP WHERE TABLENAME = #TABLENAME
END
go
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'
GO
EXEC sp_MSForEachTable 'ALTER TABLE ? ENABLE TRIGGER ALL'
go
But i get the error foreign key reference error. I know i need to drop constraint before doing it. But is there any way to do it as i cannot drop then truncate and again add each time with so many tables. Is there any unique script can we write in below which will drop constraint if exists,truncate table and add the dropped constraint again to the table again.
I'm afraid that there is no way to do that without dropping constraints,
you can write a code that extracts the constraints for the tables and drop them it's simple.
Create a temporary table and use this code to get the tables constraint and notice that the sysconstraints.status must be 1 or 3 to get foreign and primary keys:
Select SysObjects.[Name] As "Constraint Name",
Tabls.[Name] as "Table Name",
Cols.[Name] As "Column Name"
From SysObjects Inner Join
(Select [Name],[ID] From SysObjects) As Tabls
On Tabls.[ID] = Sysobjects.[Parent_Obj]
Inner Join sysconstraints On sysconstraints.Constid = Sysobjects.[ID]
Inner Join SysColumns Cols On Cols.[ColID] = sysconstraints.[ColID]
And Cols.[ID] = Tabls.[ID]
where sysconstraints.status in (1, 3)
order by [Tabls].[Name]
you gonna have to recreate these constraints again after truncate, that's simple too, but I'm not gonna do all your job :)
Even if all tabled are empty and you disable all constraints the truncate ill fail due to the mere FK existence. You really must drop it.
You can create a script to automate it (truncate all tables dropping and recreating FKs)
I found one here (use with discretion)
http://www.sqlservercentral.com/scripts/Development/62892/
Also if you just want to create a "blanket" DB you can export the script to create all objects and just populate that few (domain?) tables do you need.

Drop foreign key without knowing the name of the constraint?

I have created one table using the below command:
create table Table1(
Id int Not Null
Foreign key
references Table2(Id)
on delete cascade
on update cascade,
UserName nvarchar(150),
TimeInSeconds int Not Null
primary key(Id,TimeInSeconds)
);
But now I want to drop the foreign key.
As I haven't given a constraint name, I can't use:
Alter table <tablename>
drop foreign key <foreign key name>
Is there any way?
You can find the name of the constraint in INFORMATION_SCHEMA.TABLE_CONSTRAINTS
select CONSTRAINT_NAME
from INFORMATION_SCHEMA.TABLE_CONSTRAINTS
where TABLE_NAME = 'Table1'
Similar to Ed's Answer but you can use this to select the key name based on the table and column name.
That way you can run it in a script or maybe as a subquery to drop the constraint.
SELECT CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE TABLE_NAME = 'post'
AND COLUMN_NAME = 'userID'
Expanding on the answers since I ran into some gotchas. Also, I had 2 foreign keys declared, so I added an optional key to keep, if it's null it'll just be ignored:
declare #name varchar(255),
#table varchar(255) = 'mytable',
#column varchar(255) = 'mykeycolumn',
#validkey varchar(255) = 'mykeyIwanttokeep'
SELECT #name = CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE TABLE_NAME = #table
AND COLUMN_NAME = #column
AND (CONSTRAINT_NAME != #validkey or #validkey is null)
declare #sql varchar(1023) = 'alter table ' + #table + ' drop ' + #name
exec (#sql)
A SQL Server option:
DECLARE #foreignkey varchar(100)
DECLARE #tablename varchar(100)
DECLARE #command nvarchar(1000)
DECLARE db_cursor CURSOR FOR
SELECT fk.name, t.name
FROM sys.foreign_keys fk
JOIN sys.tables t ON t.object_id = fk.parent_object_id
WHERE t.name IN (
'table_1_name_here',
'table_2_name_here'
)
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #foreignkey, #tablename
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #command = 'ALTER TABLE ' + #tablename + ' DROP CONSTRAINT ' + #foreignkey
EXECUTE(#command)
FETCH NEXT FROM db_cursor INTO #foreignkey, #tablename
END
CLOSE db_cursor
DEALLOCATE db_cursor
The SQL selects all the constraints for the tables you care about into a cursor and drops them one by one. All you need to know are the names of the tables you want them dropped from.
To drop a foreign key use the following commands :
SHOW CREATE TABLE table_name;
ALTER TABLE table_name DROP FOREIGN KEY table_name_ibfk_3;
("table_name_ibfk_3" is constraint foreign key name assigned for unnamed constraints). It varies.
ALTER TABLE table_name DROP column_name.
If you just look at the table in enterprise manager / management studio you will be able to see the list of keys and delete it from there.
Never mind, below is Postgres syntax. It would be better if the question had sql server in the title as I didn't notice the tag
You could also drop and re-add the primary key on the parent table using cascade. This will remove any foreign keys that reference that table without you needing to know the foreign key names.
ALTER TABLE parent_table
DROP CONSTRAINT 'pk_id' CASCADE
-- add back pk
ALTER TABLE parent_table
ADD CONSTRAINT 'pk_id' PRIMARY KEY (id)
WARNING: you'd want to check all the dependencies first and if there are other tables, you'd need to add back their foreign keys. That does allow you to name the foreign keys properly when you add them back. This approach also may not be viable in a high transaction system due to the blocking transaction.
you can put:
> show create table tablename;
you will see how was created the table...columns, types...etc. and you could see your constraint name.

How do you truncate all tables in a database using TSQL?

I have a test environment for a database that I want to reload with new data at the start of a testing cycle. I am not interested in rebuilding the entire database- just simply "re-setting" the data.
What is the best way to remove all the data from all the tables using TSQL? Are there system stored procedures, views, etc. that can be used? I do not want to manually create and maintain truncate table statements for each table- I would prefer it to be dynamic.
When dealing with deleting data from tables which have foreign key relationships - which is basically the case with any properly designed database - we can disable all the constraints, delete all the data and then re-enable constraints
-- disable all constraints
EXEC sp_MSForEachTable "ALTER TABLE ? NOCHECK CONSTRAINT all"
-- delete data in all tables
EXEC sp_MSForEachTable "DELETE FROM ?"
-- enable all constraints
exec sp_MSForEachTable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"
More on disabling constraints and triggers here
if some of the tables have identity columns we may want to reseed them
EXEC sp_MSForEachTable "DBCC CHECKIDENT ( '?', RESEED, 0)"
Note that the behaviour of RESEED differs between brand new table, and one which had had some data inserted previously from BOL:
DBCC CHECKIDENT ('table_name', RESEED, newReseedValue)
The current identity value is set to
the newReseedValue. If no rows have
been inserted to the table since it
was created, the first row inserted
after executing DBCC CHECKIDENT will
use newReseedValue as the identity.
Otherwise, the next row inserted will
use newReseedValue + 1. If the value
of newReseedValue is less than the
maximum value in the identity column,
error message 2627 will be generated
on subsequent references to the table.
Thanks to Robert for pointing out the fact that disabling constraints does not allow to use truncate, the constraints would have to be dropped, and then recreated
For SQL 2005,
EXEC sp_MSForEachTable 'TRUNCATE TABLE ?'
Couple more links for 2000 and 2005/2008..
Here's the king daddy of database wiping scripts. It will clear all tables and reseed them correctly:
SET QUOTED_IDENTIFIER ON;
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; ALTER TABLE ? NOCHECK CONSTRAINT ALL'
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; ALTER TABLE ? DISABLE TRIGGER ALL'
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; DELETE FROM ?'
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; ALTER TABLE ? CHECK CONSTRAINT ALL'
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; ALTER TABLE ? ENABLE TRIGGER ALL'
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON';
IF NOT EXISTS (
SELECT
*
FROM
SYS.IDENTITY_COLUMNS
JOIN SYS.TABLES ON SYS.IDENTITY_COLUMNS.Object_ID = SYS.TABLES.Object_ID
WHERE
SYS.TABLES.Object_ID = OBJECT_ID('?') AND SYS.IDENTITY_COLUMNS.Last_Value IS NULL
)
AND OBJECTPROPERTY( OBJECT_ID('?'), 'TableHasIdentity' ) = 1
DBCC CHECKIDENT ('?', RESEED, 0) WITH NO_INFOMSGS;
Enjoy, but be careful!
The simplest way of doing this is to
open up SQL Management Studio
navigate to your database
Right-click and select Tasks->Generate Scripts (pic 1)
On the "choose Objects" screen, select the "select specific objects" option and check "tables" (pic 2)
on the next screen, select "advanced" and then change the "Script DROP and CREATE" option to "Script DROP and CREATE" (pic 3)
Choose to save script to a new editor window or a file and run as necessary.
this will give you a script that drops and recreates all your tables without the need to worry about debugging or whether you've included everything. While this performs more than just a truncate, the results are the same. Just keep in mind that your auto-incrementing primary keys will start at 0, as opposed to truncated tables which will remember the last value assigned. You can also execute this from code if you don't have access to Management studio on your PreProd or Production environments.
1.
2.
3.
Truncating all of the tables will only work if you don't have any foreign key relationships between your tables, as SQL Server will not allow you to truncate a table with a foreign key.
An alternative to this is to determine the tables with foreign keys and delete from these first, you can then truncate the tables without foreign keys afterwards.
See http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=65341 and http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=72957 for further details.
Don't do this! Really, not a good idea.
If you know which tables you want to truncate, create a stored procedure which truncates them. You can fix the order to avoid foreign key problems.
If you really want to truncate them all (so you can BCP load them for example) you would be just as quick to drop the database and create a new one from scratch, which would have the additional benefit that you know exactly where you are.
An alternative option I like to use with MSSQL Server Deveploper or Enterprise is to create a snapshot of the database immediately after creating the empty schema. At that point you can just keep restoring the database back to the snapshot.
If you want to keep data in a particular table (i.e. a static lookup table) while deleting/truncating data in other tables within the same db, then you need a loop with the exceptions in it. This is what I was looking for when I stumbled onto this question.
sp_MSForEachTable seems buggy to me (i.e. inconsistent behavior with IF statements) which is probably why its undocumented by MS.
declare #LastObjectID int = 0
declare #TableName nvarchar(100) = ''
set #LastObjectID = (select top 1 [object_id] from sys.tables where [object_id] > #LastObjectID order by [object_id])
while(#LastObjectID is not null)
begin
set #TableName = (select top 1 [name] from sys.tables where [object_id] = #LastObjectID)
if(#TableName not in ('Profiles', 'ClientDetails', 'Addresses', 'AgentDetails', 'ChainCodes', 'VendorDetails'))
begin
exec('truncate table [' + #TableName + ']')
end
set #LastObjectID = (select top 1 [object_id] from sys.tables where [object_id] > #LastObjectID order by [object_id])
end
The hardest part of truncating all tables is removing and re-ading the foreign key constraints.
The following query creates the drop & create statements for each constraint relating to each table name in #myTempTable. If you would like to generate these for all the tables, you may simple use information schema to gather these table names instead.
DECLARE #myTempTable TABLE (tableName varchar(200))
INSERT INTO #myTempTable(tableName) VALUES
('TABLE_ONE'),
('TABLE_TWO'),
('TABLE_THREE')
-- DROP FK Contraints
SELECT 'alter table '+quotename(schema_name(ob.schema_id))+
'.'+quotename(object_name(ob.object_id))+ ' drop constraint ' + quotename(fk.name)
FROM sys.objects ob INNER JOIN sys.foreign_keys fk ON fk.parent_object_id = ob.object_id
WHERE fk.referenced_object_id IN
(
SELECT so.object_id
FROM sys.objects so JOIN sys.schemas sc
ON so.schema_id = sc.schema_id
WHERE so.name IN (SELECT * FROM #myTempTable) AND sc.name=N'dbo' AND type in (N'U'))
-- CREATE FK Contraints
SELECT 'ALTER TABLE [PIMSUser].[dbo].[' +cast(c.name as varchar(255)) + '] WITH NOCHECK ADD CONSTRAINT ['+ cast(f.name as varchar(255)) +'] FOREIGN KEY (['+ cast(fc.name as varchar(255)) +'])
REFERENCES [PIMSUser].[dbo].['+ cast(p.name as varchar(255)) +'] (['+cast(rc.name as varchar(255))+'])'
FROM sysobjects f
INNER JOIN sys.sysobjects c ON f.parent_obj = c.id
INNER JOIN sys.sysreferences r ON f.id = r.constid
INNER JOIN sys.sysobjects p ON r.rkeyid = p.id
INNER JOIN sys.syscolumns rc ON r.rkeyid = rc.id and r.rkey1 = rc.colid
INNER JOIN sys.syscolumns fc ON r.fkeyid = fc.id and r.fkey1 = fc.colid
WHERE
f.type = 'F'
AND
cast(p.name as varchar(255)) IN (SELECT * FROM #myTempTable)
I then just copy out the statements to run - but with a bit of dev effort you could use a cursor to run them dynamically.
It is much easier (and possibly even faster) to script out your database, then just drop and create it from the script.
Make an empty "template" database, take a full backup. When you need to refresh, just restore using WITH REPLACE. Fast, simple, bulletproof. And if a couple tables here or there need some base data(e.g. config information, or just basic information that makes your app run) it handles that too.
This is one way to do it... there are likely 10 others that are better/more efficient, but it sounds like this is done very infrequently, so here goes...
get a list of the tables from sysobjects, then loop over those with a cursor, calling sp_execsql('truncate table ' + #table_name) for each iteration.
Run the commented out section once, populate the _TruncateList table with the tables you want truncated, then run the rest of the script. The _ScriptLog table will need to be cleaned up over time if you do this a lot.
You can modify this if you want to do all tables, just put in SELECT name INTO #TruncateList FROM sys.tables. However, you usually don't want to do them all.
Also, this will affect all foreign keys in the database, and you can modify that as well if it's too blunt-force for your application. It's not for my purposes.
/*
CREATE TABLE _ScriptLog
(
ID Int NOT NULL Identity(1,1)
, DateAdded DateTime2 NOT NULL DEFAULT GetDate()
, Script NVarChar(4000) NOT NULL
)
CREATE UNIQUE CLUSTERED INDEX IX_ScriptLog_DateAdded_ID_U_C ON _ScriptLog
(
DateAdded
, ID
)
CREATE TABLE _TruncateList
(
TableName SysName PRIMARY KEY
)
*/
IF OBJECT_ID('TempDB..#DropFK') IS NOT NULL BEGIN
DROP TABLE #DropFK
END
IF OBJECT_ID('TempDB..#TruncateList') IS NOT NULL BEGIN
DROP TABLE #TruncateList
END
IF OBJECT_ID('TempDB..#CreateFK') IS NOT NULL BEGIN
DROP TABLE #CreateFK
END
SELECT Scripts = 'ALTER TABLE ' + '[' + OBJECT_NAME(f.parent_object_id)+ ']'+
' DROP CONSTRAINT ' + '[' + f.name + ']'
INTO #DropFK
FROM .sys.foreign_keys AS f
INNER JOIN .sys.foreign_key_columns AS fc
ON f.OBJECT_ID = fc.constraint_object_id
SELECT TableName
INTO #TruncateList
FROM _TruncateList
SELECT Scripts = 'ALTER TABLE ' + const.parent_obj + '
ADD CONSTRAINT ' + const.const_name + ' FOREIGN KEY (
' + const.parent_col_csv + '
) REFERENCES ' + const.ref_obj + '(' + const.ref_col_csv + ')
'
INTO #CreateFK
FROM (
SELECT QUOTENAME(fk.NAME) AS [const_name]
,QUOTENAME(schParent.NAME) + '.' + QUOTENAME(OBJECT_name(fkc.parent_object_id)) AS [parent_obj]
,STUFF((
SELECT ',' + QUOTENAME(COL_NAME(fcP.parent_object_id, fcp.parent_column_id))
FROM sys.foreign_key_columns AS fcP
WHERE fcp.constraint_object_id = fk.object_id
FOR XML path('')
), 1, 1, '') AS [parent_col_csv]
,QUOTENAME(schRef.NAME) + '.' + QUOTENAME(OBJECT_NAME(fkc.referenced_object_id)) AS [ref_obj]
,STUFF((
SELECT ',' + QUOTENAME(COL_NAME(fcR.referenced_object_id, fcR.referenced_column_id))
FROM sys.foreign_key_columns AS fcR
WHERE fcR.constraint_object_id = fk.object_id
FOR XML path('')
), 1, 1, '') AS [ref_col_csv]
FROM sys.foreign_key_columns AS fkc
INNER JOIN sys.foreign_keys AS fk ON fk.object_id = fkc.constraint_object_id
INNER JOIN sys.objects AS oParent ON oParent.object_id = fkc.parent_object_id
INNER JOIN sys.schemas AS schParent ON schParent.schema_id = oParent.schema_id
INNER JOIN sys.objects AS oRef ON oRef.object_id = fkc.referenced_object_id
INNER JOIN sys.schemas AS schRef ON schRef.schema_id = oRef.schema_id
GROUP BY fkc.parent_object_id
,fkc.referenced_object_id
,fk.NAME
,fk.object_id
,schParent.NAME
,schRef.NAME
) AS const
ORDER BY const.const_name
INSERT INTO _ScriptLog (Script)
SELECT Scripts
FROM #CreateFK
DECLARE #Cmd NVarChar(4000)
, #TableName SysName
WHILE 0 < (SELECT Count(1) FROM #DropFK) BEGIN
SELECT TOP 1 #Cmd = Scripts
FROM #DropFK
EXEC (#Cmd)
DELETE #DropFK WHERE Scripts = #Cmd
END
WHILE 0 < (SELECT Count(1) FROM #TruncateList) BEGIN
SELECT TOP 1 #Cmd = N'TRUNCATE TABLE ' + TableName
, #TableName = TableName
FROM #TruncateList
EXEC (#Cmd)
DELETE #TruncateList WHERE TableName = #TableName
END
WHILE 0 < (SELECT Count(1) FROM #CreateFK) BEGIN
SELECT TOP 1 #Cmd = Scripts
FROM #CreateFK
EXEC (#Cmd)
DELETE #CreateFK WHERE Scripts = #Cmd
END
It is a little late but it might help someone.
I created a procedure sometimes back which does the following using T-SQL:
Store all constraints in a Temporary table
Drop All Constraints
Truncate all tables with exception of some tables, which does not need truncation
Recreate all Constraints.
I have listed it on my blog here
I do not see why clearing data would be better than a script to drop and re-create each table.
That or keep a back up of your empty DB and restore it over old one
Before truncating the tables you have to remove all foreign keys. Use this script to generate final scripts to drop and recreate all foreign keys in database. Please set the #action variable to 'CREATE' or 'DROP'.
select 'delete from ' +TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_TYPE='BASE TABLE'
where result come.
Copy and paste on query window and run the command

Resources