Truncate Table with Foreign Key constraint

Truncate Table with Foreign Key constraint

This post helps you in automating the process of Truncate Table with Foreign Key constraint”. We recently working for a client on data migration project. There was a requirement for truncating tables. But we had to face issues as all those tables are having foreign keys. So the requirement is :

  • Everytime we’ll send you a list of tables to be truncated
  • First collect all constraint details from those tables
  • Drop all foreign keys
  • Truncate tables
  • Recreate all constraints
  • If in-case of any failure the script should not fail or through any error message instead it should continue with the next object  and failed objects / constraints should be printed

We built the below stored procedure to fulfill the client requirement and it worked perfectly as expected.

Stored Procedure Creation to Truncate Table with Foreign Key constraint:


IF EXISTS(SELECT 1 FROM SYS.SYSOBJECTS WHERE NAME='USP_Truncate_Tabs' AND TYPE='P')
BEGIN
	DROP PROC USP_Truncate_Tabs;
END

GO

CREATE PROC USP_Truncate_Tabs(@String VARCHAR(7500))  
AS 
BEGIN 
SET NOCOUNT ON 
 
/*** Verify table existence if not avilable it creates anew table on master database ***/
IF NOT EXISTS(SELECT 1 FROM master.sys.sysobjects WHERE Name='Constraints' AND TYPE='U')
BEGIN
	CREATE TABLE [master].[dbo].[Constraints]
			(ID INT IDENTITY,
			DropStmt VARCHAR(1000),
			Createstmt VARCHAR(1000),
			DropStatus BIT DEFAULT(1),
			CreateStatus BIT DEFAULT(1),
			TruncateStatus BIT DEFAULT(1),
			LastUsed DATETIME DEFAULT(GETDATE()));
END

TRUNCATE TABLE [master].[dbo].[Constraints]

/*** Get the list of Tables from the input String ***/
DECLARE @Tab TABLE(ID INT IDENTITY,TabName VARCHAR(200)) 
DECLARE @SQL1 VARCHAR(8000) 
SET @SQL1='SELECT NAME FROM sysobjects  WHERE TYPE=''U'' AND name in('+(@String)+')' 
INSERT INTO @Tab EXEC(@SQL1) 
 

/*** Insert All Drop and Create dtatements into the table Constraints ***/
INSERT INTO [master].[dbo].[Constraints] (DropStmt,CreateStmt) 
SELECT 
  'ALTER TABLE [' + ForeignKeys.ForeignTableSchema +  
      '].[' + ForeignKeys.ForeignTableName +  
      '] DROP CONSTRAINT [' + ForeignKeys.ForeignKeyName + ']; ' 
,'ALTER TABLE ['+ ForeignKeys.ForeignTableSchema +  
      '].[' + ForeignKeys.ForeignTableName +  
      '] WITH CHECK ADD CONSTRAINT [' +  ForeignKeys.ForeignKeyName +  
      '] FOREIGN KEY([' + ForeignKeys.ForeignTableColumn +  
      ']) REFERENCES [' + schema_name(sys.objects.schema_id) + '].[' + 
  sys.objects.[name] + ']([' + 
  sys.columns.[name] + ']);  ' 
 from sys.objects 
  inner join sys.columns 
    on (sys.columns.[object_id] = sys.objects.[object_id]) 
  inner join ( 
    select sys.foreign_keys.[name] as ForeignKeyName 
     ,schema_name(sys.objects.schema_id) as ForeignTableSchema 
     ,sys.objects.[name] as ForeignTableName 
     ,sys.columns.[name]  as ForeignTableColumn 
     ,sys.foreign_keys.referenced_object_id as referenced_object_id 
     ,sys.foreign_key_columns.referenced_column_id as referenced_column_id 
     from sys.foreign_keys 
      inner join sys.foreign_key_columns 
        on (sys.foreign_key_columns.constraint_object_id 
          = sys.foreign_keys.[object_id]) 
      inner join sys.objects 
        on (sys.objects.[object_id] 
          = sys.foreign_keys.parent_object_id) 
        inner join sys.columns 
          on (sys.columns.[object_id] 
            = sys.objects.[object_id]) 
           and (sys.columns.column_id 
            = sys.foreign_key_columns.parent_column_id) 
    ) ForeignKeys 
    on (ForeignKeys.referenced_object_id = sys.objects.[object_id]) 
     and (ForeignKeys.referenced_column_id = sys.columns.column_id) 
 where (sys.objects.[type] = 'U') 
  and (sys.objects.[name] not in ('sysdiagrams')) 
 

/*** Drop all Constraints in the database and update the Constraints table for failed statements ***/ 
/*** From Constraints Table Status 1 - Success and Status 0 - Failed ***/
PRINT'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
PRINT'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
PRINT'@@@@@@@@@@@@@@@@   Drop Constraints @@@@@@@@@@@@@@@@@@@@'
PRINT'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
PRINT'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'

DECLARE @Sql VARCHAR(1000) 
DECLARE @i INT,@Max INT 
SELECT @Max=COUNT(1)FROM [master].[dbo].[Constraints]  
SET @i=1 

WHILE(@i<=@Max) 
BEGIN 
	SELECT @Sql=DropStmt FROM [master].[dbo].[Constraints] WHERE ID=@i 
	BEGIN TRY
		EXEC(@Sql) 
	END TRY
	BEGIN CATCH
		UPDATE [master].[dbo].[Constraints] SET DropStatus=0 WHERE ID=@i
	END CATCH
	SET @Sql='' 
	SET @i=@i+1 
END 

/*** Check for the errors in droping the constraints ***/

IF NOT EXISTS(SELECT 1 FROM [master].[dbo].[Constraints] WHERE DropStatus=0)
BEGIN
	PRINT'All foreign keys are Dropped successfully' 
END
ELSE
BEGIN
	PRINT'A result set retrived with the Failed Statements'
	SELECT CreateStmt AS'FailedtoDrop'FROM [master].[dbo].[Constraints] WHERE DropStatus=0
END


/*** Truncate the tables specified in the input string ******/
/*** It directly echos the failed statements on results window ***/
PRINT' ' 
PRINT'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
PRINT'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
PRINT'@@@@@@@@@@@@@@@@ TRUNCATE Tables @@@@@@@@@@@@@@@@@@@@@@@'
PRINT'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
PRINT'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
PRINT' ' 

DECLARE @TabName VARCHAR(200) 
SELECT @Max=COUNT(1)FROM @Tab 
SET @i=1 
WHILE(@i<=@Max) 
BEGIN 
	SELECT @TabName=TabName FROM @Tab WHERE ID=@i 
	SELECT @Sql='TRUNCATE TABLE '+@TabName 
	BEGIN TRY
		EXEC(@sql)
	END TRY
	BEGIN CATCH
		UPDATE [master].[dbo].[Constraints] SET TruncateStatus=0 WHERE ID=@i
	END CATCH
	SET @Sql='' 
	SET @i=@i+1 
END 

/*** Check for the errors in Truncating the Tables ***/

IF NOT EXISTS(SELECT 1 FROM [master].[dbo].[Constraints] WHERE TruncateStatus=0)
BEGIN
	PRINT'All specified Tables are Truncated successfully' 
END
ELSE
BEGIN
	PRINT'A result set retrived with the Failed Statements'
	SELECT CreateStmt AS'FailedtoTruncate'FROM [master].[dbo].[Constraints] WHERE TruncateStatus=0
END

/*** Recreate all Constraints in the database and update the Constraints table for failed statements ***/ 
/*** From Constraints Table Status 1 - Success and Status 0 - Failed ***/

PRINT' ' 
PRINT'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
PRINT'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
PRINT '@@@@@@@@@@@@@@   Recreate Constraints   @@@@@@@@@@@@@@@@' 
PRINT'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
PRINT'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
PRINT' '

SELECT @Max=COUNT(1)FROM [master].[dbo].[Constraints]  
SET @i=1 
WHILE(@i<=@Max) 
	BEGIN 
		SELECT @Sql=CreateStmt FROM [master].[dbo].[Constraints] WHERE ID=@i 
	BEGIN TRY
		EXEC(@Sql) 
	END TRY
	BEGIN CATCH
		UPDATE [master].[dbo].[Constraints] SET CreateStatus=0 WHERE ID=@i
	END CATCH
	SET @Sql='' 
	SET @i=@i+1 
END 

/*** Check for the errors in recreating the constraints ***/
IF NOT EXISTS(SELECT 1 FROM [master].[dbo].[Constraints] WHERE CreateStatus=0)
	PRINT'All foreign keys are recreated successfully'
ELSE
	PRINT'Foreign keys are recreated with errors look into Summary'

/***** Summary   ******/
PRINT' '
PRINT'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
PRINT'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
PRINT'@@@@@@@@@@@@@@@@@@@@@@@  SUMMARY  @@@@@@@@@@@@@@@@@@@@@@'
PRINT'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
PRINT'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
PRINT' '

IF NOT EXISTS(SELECT 1 FROM [master].[dbo].[Constraints] WHERE CreateStatus=0)
BEGIN
	PRINT'All foreign keys are recreated successfully'
END
ELSE
BEGIN
	PRINT'A result set retrived with the Failed Statements'
	SELECT CreateStmt AS'FailedtoRecreate'FROM [master].[dbo].[Constraints] WHERE CreateStatus=0
END

/**** Second Attempt to Recreating the failed constraints if any ****/

IF EXISTS(SELECT 1 FROM [master].[dbo].[Constraints] WHERE CreateStatus=0)
BEGIN
	PRINT' '
	PRINT'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
	PRINT'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
	PRINT'@@@@@@ Final Atempt to Recreate Constraints   @@@@@@@@@@'
	PRINT'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
	PRINT'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
	PRINT' '

	DECLARE @Recreate Table(ID INT IDENTITY,ConID INT,CreateStmt VARCHAR(1000))
	INSERT INTO @Recreate (ConID,CreateStmt)SELECT ID,CreateStmt FROM [master].[dbo].[Constraints] WHERE CreateStatus=0
	SELECT @Max=COUNT(1)FROM @Recreate
	SET @i=1 
	SET @sql=''
	WHILE(@i<=@Max)
		BEGIN 
		SELECT @Sql=CreateStmt FROM @Recreate WHERE ID=@i   
		BEGIN TRY
			EXEC(@Sql)
			UPDATE [master].[dbo].[Constraints] SET CreateStatus=1 WHERE ID IN(
			SELECT ConID FROM @Recreate WHERE ID=@i)
		END	TRY
		BEGIN	CATCH
			PRINT'Final Attmept also Failed to Execute '+@sql
		END CATCH
		SET @Sql='' 
		SET @i=@i+1 
		END
	PRINT' '
	IF NOT EXISTS(SELECT 1 FROM [master].[dbo].[Constraints] WHERE CreateStatus=0)
	PRINT'All foreign keys are recreated successfully in Final Attempt'
	ELSE
	PRINT'Final Attempt is also filed in recreating all foreign keys there might be problem with domain intigrity'
	PRINT' '

END

END 

 

Example:

EXEC USP_Truncate_Tabs ”’DEPT”,”EMP_ADD”,”EMP”,”Item”,”Sales”’

 

Output is Something like below

Posted in SQL Development, SQL Scripts, SQL Server DBA | Tagged , , , , | 1 Comment

How to Truncate only the Selected Tables from Database

How to Truncate only the Selected Tables from Database

How to Truncate only the Selected Tables from Database? This stored procedure helps you out in truncating the selected tables. These tables has to be passed as a string parameter to the stored procedure.  

 
 
We came up with a stored procedure. Here we go.
 
--EXEC USP_Truncate_Tabs '''MEMBER_DIM'',''CLAIM_FACT'',''CLAIM_TYPE_DIM'',''POS_TYPE_DIM'''

CREATE PROC USP_Truncate_Tabs(@String VARCHAR(7500))
AS
BEGIN
SET NOCOUNT ON
DECLARE @Constraints TABLE(ID INT IDENTITY,DropStmt VARCHAR(1000),CreateStmt VARCHAR(1000))
DECLARE @Tab TABLE(ID INT IDENTITY,TabName VARCHAR(200))
DECLARE @SQL1 VARCHAR(8000)
SET @SQL1='SELECT NAME FROM sysobjects  WHERE TYPE=''U'' AND name in('+(@String)+')'

/** Getting only selected tables details into @Tab **/
INSERT INTO @Tab EXEC(@SQL1)

/** Insert all Create and Drop Constraint Statements into a Temp Table *******/
 
INSERT INTO @Constraints (DropStmt,CreateStmt)
SELECT
  'ALTER TABLE ['+ ForeignKeys.ForeignTableSchema +
      '].['+ ForeignKeys.ForeignTableName +
      '] DROP CONSTRAINT [' + ForeignKeys.ForeignKeyName + ']; '
,'ALTER TABLE ['+ ForeignKeys.ForeignTableSchema +
      '].['+ ForeignKeys.ForeignTableName +
      '] WITH CHECK ADD CONSTRAINT ['+  ForeignKeys.ForeignKeyName +
      '] FOREIGN KEY(['+ ForeignKeys.ForeignTableColumn +
      ']) REFERENCES [' + schema_name(sys.objects.schema_id) + '].[' +
  sys.objects.[name] + ']([' +
  sys.columns.[name] + ']);  '
 from sys.objects
  inner join sys.columns
    on (sys.columns.[object_id] = sys.objects.[object_id])
  inner join (
    select sys.foreign_keys.[name] as ForeignKeyName
     ,schema_name(sys.objects.schema_id) as ForeignTableSchema
     ,sys.objects.[name] as ForeignTableName
     ,sys.columns.[name]  as ForeignTableColumn
     ,sys.foreign_keys.referenced_object_id as referenced_object_id
     ,sys.foreign_key_columns.referenced_column_id as referenced_column_id
     from sys.foreign_keys
      inner join sys.foreign_key_columns
        on (sys.foreign_key_columns.constraint_object_id
          = sys.foreign_keys.[object_id])
      inner join sys.objects
        on (sys.objects.[object_id]
          = sys.foreign_keys.parent_object_id)
        inner join sys.columns
          on (sys.columns.[object_id]
            = sys.objects.[object_id])
           and (sys.columns.column_id
            = sys.foreign_key_columns.parent_column_id)
    ) ForeignKeys
    on (ForeignKeys.referenced_object_id = sys.objects.[object_id])
     and (ForeignKeys.referenced_column_id = sys.columns.column_id)
 where (sys.objects.[type] = 'U')
  and (sys.objects.[name] not in ('sysdiagrams'))

/*** Drop all constraints in Database ****/
 
DECLARE @Sql VARCHAR(1000)
DECLARE @i INT,@Max INT
SELECT @Max=COUNT(1)FROM @Constraints
SET @i=1
WHILE(@i<=@Max)
BEGIN
SELECT @Sql=DropStmt FROM @Constraints WHERE ID=@i
EXEC(@Sql)
IF(@@ERROR<>0)
BEGIN
PRINT'Failed to Drop the Constraint : '+@Sql
END
SET @Sql=''
SET @i=@i+1
END
PRINT'All foreign keys are dropped successfully'

 
/*** Truncate selected Tables ****/
 

DECLARE @TabName VARCHAR(200)
SELECT @Max=COUNT(1)FROM @Tab
SET @i=1
WHILE(@i<=@Max)
BEGIN
SELECT @TabName=TabName FROM @Tab WHERE ID=@i
SELECT @Sql='TRUNCATE TABLE '+@TabName
EXEC(@Sql)
IF(@@ERROR<>0)
BEGIN
PRINT'Failed to Run the statement : '+@Sql
END
PRINT'Table '+@TabName+' Truncated'
SET @Sql=''
SET @i=@i+1
END

PRINT'All tables are truncated successfully'

/*** Recreate all constraints in Database ****/
 


SELECT @Max=COUNT(1)FROM @Constraints
SET @i=1
WHILE(@i<=@Max)
BEGIN
SELECT @Sql=CreateStmt FROM @Constraints WHERE ID=@i
EXEC(@Sql)
IF(@@ERROR<>0)
BEGIN
PRINT'Failed to Recreate the Constraint : '+@Sql
END
SET @Sql=''
SET @i=@i+1
END
PRINT'All foreign keys are recreated successfully'

END

/*** Execute SP to truncate the tables Emp, Dept, Emp_Add ***/
 
 
EXEC USP_Truncate_Tabs '''Dept'',''Emp'',''Emp_Add'''
 

 
 Output is like below

 

Posted in SQL Scripts | Tagged , , , , | Leave a comment

How to rebuild Master Database in SQL Server

How to rebuild Master Database in SQL Server

We recently resolved a request from a client that he is not able to access a SQL machine. We have logged into the sql box and we cam to know that the master database has been corrupted. IT is a SQL Server 2008 machine.

We generally use the statement shown below, using the “REBUILDDATABASE” option in setup.exe and the “/qn” parameter for installation to run silently:

Here is the script help us to know how to rebuild a master dtaabase in sql server

start /wait  setup.exe / qn
INSTANCENAME=  
REINSTALL=SQL_Engine
REBUILDDATABASE=1 
SAPWD=

 

We wondered , we found that the statement doe’s not work and still the problem alive. We almost had a 108 rounds around the Google and finally found the solution from a blog. It was really helped us in resolving the issue. We ran the below statement

setup.exe
/QUIET
/ACTION=REBUILDDATABASE 
/INSTANCENAME=instance_name 
/SQLSYSADMINACCOUNTS= accounts 
[/SAPWD=password] 
[/SQLCOLLATION=collation_name]

Thank God the database backed up and services were started , we have restored the master database with the latest backup and all the databases were online w/o any issue

 

Posted in SQL Scripts, SQL Server DBA | Tagged , , , , , , | Leave a comment