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
Related
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.
I have gone thorough these previous questions Q1, Q2, Q3. Using this I can catch my exact constraint name. But it is not enough for me.
For example I have done somthing
ALTER TABLE dbo.Documents ADD ShowOnHandset BIT NOT NULL DEFAULT 'FALSE'
Here automatically my constrant named by the machine was DF__Documents__ShowO__7AB2122C on my machine. But I have run the same script in multiple PC, on those PC those constraint are almost same except the last hashed value. DF__Documents__ShowO__54A20B0D DF__Documents__ShowO__5D5216D7
I have seen that the last 8 bit hashed value is not similar. But I need to remove this constraint from all table and I want to replace them with
ALTER TABLE dbo.Documents ADD ShowOnHandset BIT NOT NULL DEFAULT ((1))
But I can't identify the the exact constraint name, so how can I drop it using a single script?
I have found hard-coded solution by those mentioned questions. But I need a single script to do it. Please help me to solve this.
I can catch the constraint name using this code
select name from sys.objects where name like 'DF__Documents__ShowO%'
I know the way how to delete it. Here it is.
ALTER TABLE dbo.AppSystems DROP constraint [constraint_name]
But I am unable to do it. Because I couldn't put the value constraint_name even if I can caught it. So how could I put this name here to drop it.
Update Modified the Question.
Run this and output as text, then copy the result and run in another query window
Fritz with the code below to ADD the updated constraint:
;With cte As (select object_id From sys.objects where name like 'DF__Documents__ShowO%')
Select 'Alter Table ' + Object_Name(df.object_id) + N' Add Constraint Default (1) For ShowOnHandset'
From sys.default_constraints As df
Join cte As c
On c.object_id = df.object_id
This deletes the constraints
;With cte As (select object_id From sys.objects where name like 'DF__Documents__ShowO%')
Select 'Alter Table ' + Object_Name(df.object_id) + N' Drop Constraint [' + df.Name + ']'
From sys.default_constraints As df
Join cte As c
On c.object_id = df.object_id
In MS SQL you can specify constraint name explicit:
ALTER TABLE dbo.Documents ADD ShowOnHandset BIT NOT NULL CONSTRAINT DF_Documents_ShowOnHandset DEFAULT 'FALSE'
Try dynamic query:
Declare #MyVariable varchar(max)
Declare #Variable varchar(max)
Set #MyVariable=(Select name from sys.objects
where parent_object_id=Object_ID('Documents','U') and name like 'DF__Documents__Show%')
Set #variable='ALTER TABLE dbo.AppSystems DROP constraint' +#MyVariable
Exec(#variable)
One of our SQL Databases is a sync of somebody else's Database. There are about 100 tables in their database, and about 120 in ours.
In ours, we have a few additional tables that help us do mapping and track other data. As a part of our additional tables, we create Foreign Keys onto some of the DBO Tables that are Sync'd from our provider.
Therefore, a Customers table that is sync'd from our Provider now has Foreign Key constraints on a mySchema.Receipts table, which has a CustomerID field.
The Provider's Sync broke, and they said that they cannot Drop the Customers table in order to Sync the data, because it now says there is a Foriegn key against Customers.
Isn't there a way I can tell them in SQL that SQL can like... ignore Foriegn Key constraints when Sync'ing or something?
If the sync job is deleting data from the target database, you can disable constraints, and then enable them again after the sync. If your sync job is truncating tables or drop and rebuilding tables, them the foreign key constraints need to be dropped, then rebuilt again after the sync.
Using the "delete from target" approach:
If target tables are part of the "dbo" schema, your process could look like:
(1) Disable all foreign keys constrains in target database.
Example:
exec sp_MSforeachtable 'IF ''?'' like ''%[dbo]%'' ALTER TABLE ? NOCHECK CONSTRAINT ALL;'
(2) Delete all data from the target tables
(3) Copy all data from the source to the target tables, including identity column data if needed.
(4) Restore all foreign keys constrains in target database.
Example:
exec sp_MSforeachtable 'IF ''?'' like ''%[dbo]%'' ALTER TABLE ? CHECK CONSTRAINT ALL;'
** To help further automate this, take advantage of the INFORMATION_SCHEMA.TABLES view in SQL Server.
SELECT 'dbo.' + TABLE_NAME as TableName, 'SELECT * FROM dbo.['+ TABLE_NAME +'];' AS Script FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' and TABLE_NAME NOT IN (comma delimited list of tables to exclude)
If needed, the below script will query all of the foreign key constraints:
IF OBJECT_ID('tempdb..#TEMPCONS') IS NOT NULL DROP TABLE #TEMPCONS;
SELECT KCU1.TABLE_SCHEMA, KCU1.TABLE_NAME, KCU1.CONSTRAINT_NAME, KCU1.COLUMN_NAME, KCU1.ORDINAL_POSITION, RC.UPDATE_RULE, RC.DELETE_RULE,
KCU2.TABLE_NAME AS REF_TABLE_NAME, KCU2.CONSTRAINT_NAME AS REF_CONSTRAINT_NAME, KCU2.COLUMN_NAME AS REF_COLUMN_NAME, KCU2.ORDINAL_POSITION AS REF_ORDINAL_POSITION,
KCU2.TABLE_SCHEMA AS REF_TABLE_SCHEMA INTO #TEMPCONS
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC INNER JOIN
INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU1 ON KCU1.CONSTRAINT_CATALOG = RC.CONSTRAINT_CATALOG AND
KCU1.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA AND KCU1.CONSTRAINT_NAME = RC.CONSTRAINT_NAME INNER JOIN
INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU2 ON KCU2.CONSTRAINT_CATALOG = RC.UNIQUE_CONSTRAINT_CATALOG AND
KCU2.CONSTRAINT_SCHEMA = RC.UNIQUE_CONSTRAINT_SCHEMA AND KCU2.CONSTRAINT_NAME = RC.UNIQUE_CONSTRAINT_NAME AND
KCU2.ORDINAL_POSITION = KCU1.ORDINAL_POSITION
ORDER BY TABLE_NAME, CONSTRAINT_NAME, ORDINAL_POSITION;
ALTER TABLE #TEMPCONS ADD COLUMN_LIST VARCHAR(MAX), REF_COLUMN_LIST VARCHAR(MAX);
-- Rows to column concatenation
DECLARE #COLUMN_NAME varchar(MAX), #Columns VARCHAR(MAX);
UPDATE #TEMPCONS SET #Columns = COLUMN_LIST = COALESCE(CASE COALESCE(#COLUMN_NAME, '')
WHEN CONSTRAINT_NAME THEN #Columns + ', ' + '['+ COLUMN_NAME +']' ELSE '['+ COLUMN_NAME +']' END, ''), #COLUMN_NAME = CONSTRAINT_NAME;
UPDATE #TEMPCONS SET #Columns = REF_COLUMN_LIST = COALESCE( CASE COALESCE(#COLUMN_NAME, '')
WHEN CONSTRAINT_NAME THEN #Columns + ', ' + '['+REF_COLUMN_NAME +']' ELSE '['+REF_COLUMN_NAME +']' END, ''), #COLUMN_NAME = CONSTRAINT_NAME;
SELECT TABLE_SCHEMA, TABLE_NAME, CONSTRAINT_NAME, UPDATE_RULE, DELETE_RULE, MAX(COLUMN_LIST) AS COLUMN_LIST,
REF_TABLE_SCHEMA, REF_TABLE_NAME, REF_CONSTRAINT_NAME, MAX(REF_COLUMN_LIST) AS REF_COLUMN_LIST
FROM #TEMPCONS
GROUP BY REF_TABLE_SCHEMA, TABLE_SCHEMA, TABLE_NAME, CONSTRAINT_NAME, UPDATE_RULE, DELETE_RULE, REF_TABLE_NAME, REF_CONSTRAINT_NAME;
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.
I want to remove foreign key from another table so i can insert values of my choice.
I am new in databases so please tell me correct sql query to drop or remove foreign key value.
Try following
ALTER TABLE <TABLE_NAME> DROP CONSTRAINT <FOREIGN_KEY_NAME>
Refer : http://www.w3schools.com/sql/sql_foreignkey.asp
Its wrong to do that in refer to referential integrity, because once its broken its not easy to turn it on again without having to go through the records and delete the ones which breaks the constraints.
Anyway the Syntax is as follows:
ALTER TABLE Tablename DROP CONSTRAINT ContName;
See MSDN:
Delete Primary Keys
Delete Foreign Key Relationships
ALTER TABLE [TableName] DROP CONSTRAINT [CONSTRAINT_NAME]
But, be careful man, once you do that, you may never get a chance back, and you should read some basic database book see why we need foreign key
To remove all the constraints from the DB:
SELECT 'ALTER TABLE ' + Table_Name +' DROP CONSTRAINT ' + Constraint_Name
FROM Information_Schema.CONSTRAINT_TABLE_USAGE
You should consider (temporarily) disabling the constraint before you completely delete it.
If you look at the table creation TSQL you will see something like:
ALTER TABLE [dbo].[dbAccounting] CHECK CONSTRAINT [FK_some_FK_constraint]
You can run
ALTER TABLE [dbo].[dbAccounting] NOCHECK CONSTRAINT [FK_some_FK_constraint]
... then insert/update a bunch of values that violate the constraint, and then turn it back on by running the original CHECK statement.
(I have had to do this to cleanup poorly designed systems I've inherited in the past.)
Drop all the foreign keys of a table:
USE [Database_Name]
DECLARE #FOREIGN_KEY_NAME VARCHAR(100)
DECLARE FOREIGN_KEY_CURSOR CURSOR FOR
SELECT name FOREIGN_KEY_NAME FROM sys.foreign_keys WHERE parent_object_id = (SELECT object_id FROM sys.objects WHERE name = 'Table_Name' AND TYPE = 'U')
OPEN FOREIGN_KEY_CURSOR
----------------------------------------------------------
FETCH NEXT FROM FOREIGN_KEY_CURSOR INTO #FOREIGN_KEY_NAME
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #DROP_COMMAND NVARCHAR(150) = 'ALTER TABLE Table_Name DROP CONSTRAINT' + ' ' + #FOREIGN_KEY_NAME
EXECUTE Sp_executesql #DROP_COMMAND
FETCH NEXT FROM FOREIGN_KEY_CURSOR INTO #FOREIGN_KEY_NAME
END
-----------------------------------------------------------------------------------------------------------------
CLOSE FOREIGN_KEY_CURSOR
DEALLOCATE FOREIGN_KEY_CURSOR
Depending on the DB you are using there's a syntax or another.
If you're using Oracle you have to put what the other users told you:
ALTER TABLE table_name DROP CONSTRAINT fk_name;
But if you use MySQL then this will give you a syntax error, instead you can type:
ALTER TABLE table_name DROP INDEX fk_name;
firstly use
show create table table_name;
to see the descriptive structure of your table.
There you may see constraints respective to foreign keys you used in that table.
First delete the respective constraint with
alter table table_name drop constraint constraint_name;
and then delete the respective foreign keys or column you wanted...GoodLuck!!
ALTER TABLE table
DROP FOREIGN KEY fk_key
EDIT: didn't notice you were using sql-server, my bad
ALTER TABLE table
DROP CONSTRAINT fk_key
Use those queries to find all FKs:
Declare #SchemaName VarChar(200) = 'Schema Name'
Declare #TableName VarChar(200) = 'Table name'
-- Find FK in This table.
SELECT
'IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N''' +
'[' + OBJECT_SCHEMA_NAME(FK.parent_object_id) + '].[' + FK.name + ']'
+ ''') AND parent_object_id = OBJECT_ID(N''' +
'[' + OBJECT_SCHEMA_NAME(FK.parent_object_id) + '].['
+ OBJECT_NAME(FK.parent_object_id) + ']' + ''')) ' +
'ALTER TABLE ' + OBJECT_SCHEMA_NAME(FK.parent_object_id) +
'.[' + OBJECT_NAME(FK.parent_object_id) +
'] DROP CONSTRAINT ' + FK.name
, S.name , O.name, OBJECT_NAME(FK.parent_object_id)
FROM sys.foreign_keys AS FK
INNER JOIN Sys.objects As O
ON (O.object_id = FK.parent_object_id )
INNER JOIN SYS.schemas AS S
ON (O.schema_id = S.schema_id)
WHERE
O.name = #TableName
And S.name = #SchemaName
-- Find the FKs in the tables in which this table is used
SELECT
' IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N''' +
'[' + OBJECT_SCHEMA_NAME(FK.parent_object_id) + '].[' + FK.name + ']'
+ ''') AND parent_object_id = OBJECT_ID(N''' +
'[' + OBJECT_SCHEMA_NAME(FK.parent_object_id) + '].['
+ OBJECT_NAME(FK.parent_object_id) + ']' + ''')) ' +
' ALTER TABLE ' + OBJECT_SCHEMA_NAME(FK.parent_object_id) +
'.[' + OBJECT_NAME(FK.parent_object_id) +
'] DROP CONSTRAINT ' + FK.name
, S.name , O.name, OBJECT_NAME(FK.parent_object_id)
FROM sys.foreign_keys AS FK
INNER JOIN Sys.objects As O
ON (O.object_id = FK.referenced_object_id )
INNER JOIN SYS.schemas AS S
ON (O.schema_id = S.schema_id)
WHERE
O.name = #TableName
And S.name = #SchemaName
Alternatively, you can also delete a Foreign Key Constraint from the SQL Server Management Studio itself. You can try it if the commands do not work.
Expand your database view.
Right Click on Table which has foreign key constraint. Choose Design. A tab with the information about table columns will open.
Right click on the column which has the foreign key reference. Or you can right click on any column. Choose Relationships.
A list of relationships will appear (if you have one) in a pop up window.
From there you can delete the foreign key constraint.
I hope that helps
If you find yourself in a situation where the FK name of a table has been auto-generated and you aren't able to view what it exactly is (in the case of not having rights to a database for instance) you could try something like this:
DECLARE #table NVARCHAR(512), #sql NVARCHAR(MAX);
SELECT #table = N'dbo.Table';
SELECT #sql = 'ALTER TABLE ' + #table
+ ' DROP CONSTRAINT ' + NAME + ';'
FROM sys.foreign_keys
WHERE [type] = 'F'
AND [parent_object_id] = OBJECT_ID(#table);
EXEC sp_executeSQL #sql;
Build up a stored proc which drops the constraint of the specified table without specifying the actual FK name. It drops the constraint where the object [type] is equal to F (Foreign Key constraint).
Note: if there are multiple FK's in the table it will drop them all. So this solution works best if the table you are targeting has just one FK.
If you don't know foreign key constraint name then try this to find it.
sp_help 'TableName'
additionally for different schema
sp_help 'schemaName.TableName'
then
ALTER TABLE <TABLE_NAME> DROP CONSTRAINT <FOREIGN_KEY_NAME>
To be on the safer side, just name all your constraints and take note of them in the comment section.
ALTER TABLE[table_name]
DROP CONSTRAINT Constraint_name
alter table <referenced_table_name> drop primary key;
Foreign key constraint will be removed.