loop through all tables and delete records - sql-server

I'm new to MsSql and I'm not sure if this can be done but I figured I'd ask before I want on my way with the current process..
I need to create a script that loops through all tables in a database and deletes the rows where CorporationId = "xxx". There are a few tables that do not have this column, but of my ~50 tables, only 1 or two do not.
I can individually delete the records in the table with this:
USE MyDatabase
DECLARE #CorporationId UniqueIdentifier
DECLARE #TokenId UniqueIdentifier
DECLARE #CompanyCode nChar(3)
SET #CorporationId = '52D3AEFE-8EBD-4669-8096-4596FE83BB36'
print 'Starting Web.GasOrder'
DELETE FROM Web.GasOrder
WHERE CorporationId = #CorporationId
print 'Starting Web.GasOrderNumber'
DELETE FROM Web.GasOrderNumber
WHERE CorporationId = #CorporationId
etc..
But this is getting tedious creating one for each table.
Of course, some of the tables have relationships on them.
Is there an easy way to do this or do I need to do it manually for each table?
UPDATE
Most of the options that I have tried run into problems with relationships and give me an error.

sp_MSForEachTable is an undocumented stored procedure which will run a command for each table in the database:
USE MyDatabase
DECLARE #CorporationId VARCHAR(50)
SET #CorporationId = '52D3AEFE-8EBD-4669-8096-4596FE83BB36'
DECLARE #Sql VARCHAR(MAX)
SET #Sql = '
IF COL_LENGTH(''?'',''CorporationId'') IS NOT NULL
BEGIN
DELETE FROM Web.?
WHERE CorporationId = ''' + #CorporationId + '''
END
'
EXEC sp_MSForEachTable #Sql

Here's another one... could easily be changed to a stored procedure...
Declare #corpID Nvarchar(256)
Set #corpID = 'xxx'
If Object_ID('tempdb..#tables') Is Not Null Drop Table #tables
Create Table #tables (tID Int, SchemaName Nvarchar(256), TableName Nvarchar(256))
Insert #tables
Select Row_Number() Over (Order By s.name, so.name), s.name, so.name
From sysobjects so
Join sys.schemas s
On so.uid = s.schema_id
Join syscolumns sc
On so.id = sc.id
Where so.xtype = 'u'
And sc.name = 'CorporationId'
Declare #SQL Nvarchar(Max),
#schema Nvarchar(256),
#table Nvarchar(256),
#iter Int = 1
While Exists (Select 1
From #tables)
Begin
Select #schema = SchemaName,
#table = TableName
From #tables
Where tID = #iter
If Exists (Select 1
From sysobjects o
Join sys.schemas s1
On o.uid = s1.schema_id
Join sysforeignkeys fk
On o.id = fk.rkeyid
Join sysobjects o2
On fk.fkeyid = o2.id
Join sys.schemas s2
On o2.uid = s2.schema_id
Join #tables t
On o2.name = t.TableName Collate Database_Default
And s2.name = t.SchemaName Collate Database_Default
Where o.name = #table
And s1.name = #schema)
Begin
Update t
Set tID = (Select Max(tID) From #tables) + 1
From #tables t
Where tableName = #table
And schemaName = #schema
Set #iter = #iter + 1
End
Else
Begin
Set #Sql = 'Delete t
From [' + #schema + '].[' + #table + '] t
Where CorporationId = ''' + #corpID + ''''
Exec sp_executeSQL #SQL;
Delete t
From #tables t
Where tableName = #table
And schemaName = #schema
Set #iter = #iter + 1
End
End

You could run a query like this:
SELECT 'DELETE FROM [' + s.name + '].[' + t.name + '] WHERE CorporationId = ''52D3AEFE-8EBD-4669-8096-4596FE83BB36'''
FROM sys.columns c
inner join sys.tables t
ON t.object_id= c.object_id
inner join sys.schemas s
ON s.schema_id = t.schema_id
where c.name = 'CorporationId'
and then either copy and paste the results into a new query window and execute the new query or iterate over the results with a cursor and execute each result with the exec statement.

Here is a Sql Fiddle that proves the below query
You can get the tables from this query:
SELECT Name, IsChecked = 0
INTO #Tables
FROM sys.Tables
WHERE EXISTS
(
SELECT * FROM sys.columns
WHERE object_id = OBJECT_ID(sys.Tables.Name) AND sys.columns.Name = 'blah'
)
Then, you can create a dynamic query and execute it for the tables that you found
WHILE(SELECT COUNT(*) FROM #Tables WHERE IsChecked = 0) > 0
BEGIN
SELECT TOP 1 #TableName = Name FROM #Tables WHERE IsChecked = 0
SET #DeleteQuery = 'DELETE FROM ' + #TableName + ' WHERE CorporationID = ''' + #CorporationId + ''''
EXECUTE sp_executeSQL #DeleteQuery;
UPDATE #Tables SET IsChecked = 1 WHERE Name = #TableName
END

Related

T-SQL trigger - delete updated record if condition is met

I need to write a trigger for all tables in a Microsoft SQL Server 2017 Enterprise database that if column is_deleted = 1 and change_user = 'purge', then delete the updated row instead of updating it.
This needs to be a dynamic trigger so that each table trigger does not need to have the table explicitly defined. The environment has over 1200 tables.
However, I only want the delete statement to delete the inserted record and not go through the entire table which I believe the below trigger would do. The environment has tables with 100+ million records and a delete statement that would run through the whole table would create a lot of overhead and would likely not keep up with 2 million transactions per hour.
CREATE OR ALTER TRIGGER [PurgeDelete]
ON [TriggerTest]
AFTER UPDATE
AS
DECLARE #SQL NVARCHAR(1000)
DECLARE #SchemaName NVARCHAR(100) = (SELECT OBJECT_SCHEMA_NAME( parent_id ) FROM sys.triggers WHERE object_id = ##PROCID)
DECLARE #TableName NVARCHAR(100) = (SELECT OBJECT_NAME( parent_id ) tableName FROM sys.triggers WHERE object_id = ##PROCID)
IF (ROWCOUNT_BIG() = 0)
RETURN;
IF EXISTS (SELECT 1
FROM Inserted AS i
WHERE is_deleted = 1
AND change_user = 'purge')
BEGIN
SET #SQL = 'DELETE FROM ' + #SchemaName + '.' + #TableName + ' WHERE is_deleted = 1 AND change_user = ''purge'''
EXECUTE sp_executesql #SQL
END
GO
UPDATE [TriggerTest]
SET [Description] = 'Test 1a', [is_deleted] = 1, [change_user] = 'Purge'
WHERE [TriggerTestId] = 1
SELECT * FROM [TriggerTest];
GO
Your trigger code needs to access the inserted and deleted tables. You cannot do this with dynamic SQL, as you are then in a different scope.
In any case, if you want a dynamic trigger, I would advise instead to make a script to generate the triggers dynamically, but the triggers would be static once generated.
So the basic template would be like this:
CREATE OR ALTER TRIGGER TriggerTest_PurgeDelete
ON dbo.TriggerTest
AFTER UPDATE
AS
SET NOCOUNT ON;
IF EXISTS (SELECT 1
FROM inserted AS i
WHERE is_deleted = 1
AND change_user = 'purge')
BEGIN
DELETE FROM t
FROM dbo.TriggerTest t
JOIN inserted i ON i.YourPrimaryKey = t.YourPrimaryKey
WHERE i.is_deleted = 1
AND i.change_user = 'purge';
END;
Now you just need a script that can generate this dynamically
-- user provided table/schema name here
DECLARE #schema sysname = 'dbo';
DECLARE #table sysname = 'TriggerTest';
DECLARE #quoted nvarchar(1000) = QUOTENAME(#schema) + '.' + QUOTENAME(#table);
DECLARE #primaryKeys nvarchar(max);
SELECT #primaryKeys = STRING_AGG(
'i.' + QUOTENAME(c.name) + ' = t.' + QUOTENAME(c.name),
' AND '
)
FROM sys.tables t
JOIN sys.schemas s ON s.schema_id = t.schema_id
JOIN sys.indexes i ON t.object_id = i.object_id
AND i.is_primary_key = 1
JOIN sys.index_columns ic ON ic.object_id = i.object_id
AND ic.index_id = i.index_id
JOIN sys.columns c ON c.object_id = t.object_id
AND c.column_id = i.column_id
WHERE s.name = #schema
AND t.name = #table
AND pk.type = 'P';
DECLARE #sql nvarchar(max) = '
CREATE OR ALTER TRIGGER ' + QUOTENAME(#schema + '_' + #table + '_PD') + '
ON ' + #quoted + '
AFTER UPDATE
AS
SET NOCOUNT ON;
IF EXISTS (SELECT 1
FROM inserted AS i
WHERE is_deleted = 1
AND change_user = ''purge'')
BEGIN
DELETE FROM t
FROM ' + #quoted + ' t
JOIN inserted i ON ' + #primaryKeys + '
WHERE i.is_deleted = 1
AND i.change_user = ''purge'';
END;
';
EXEC sp_executesql #sql;
You can in theory use an INSTEAD OF trigger, which may possibly be more efficient if the delete will happen often, but it's also more difficult to manage, as it needs updating every time you ALTER any of the columns in the table.
You could use,
DECLARE #IsDeleted INT
DECLARE #ChangeUser VARCHAR(10)
SELECT
#IsDeleted = I.is_deleted
,#ChangeUser = I.change_user
FROM INSERTED I
IF (UPDATE (is_deleted) OR UPDATE (change_user))
BEGIN
IF (#IsDeleted = 1 AND #ChangeUser = 'purge')
BEGIN
-- Execute the delete
END
END

Iterate through all DBs - Get constraints in all tables

I'm trying to iterate through all databases by listing all table constraints. I've achieved the following:
DECLARE #sql nvarchar(max) = ''
SET #sql =
'
USE ?
select con.[name] as constraint_name,
schema_name(t.schema_id) + ''.'' + t.[name] as [table],
col.[name] as column_name,
con.[definition],
case when con.is_disabled = 0
then ''Active''
else ''Disabled''
end as [status]
from sys.check_constraints con
left outer join sys.objects t
on con.parent_object_id = t.object_id
left outer join sys.all_columns col
on con.parent_column_id = col.column_id
and con.parent_object_id = col.object_id
order by con.name
'
PRINT #sql
EXEC sp_MSforeachdb #sql
I would like to have the query UNION all of my results in one clean select.
Can anyone help?
Using SQL Server 2016.
One way is to insert the intermediate results into a temp table. Below is an example that also includes the database name in the results.
CREATE TABLE #results (
[database_name] sysname
,[constraint_name] nvarchar(128)
,[table] nvarchar(257)
,[column_name] nvarchar(128)
,[definition] nvarchar(max)
,[status] varchar(8)
);
DECLARE #sql nvarchar(max) = ''
SET #sql =
N'
USE [?];
INSERT INTO #results
select
N''?'' as database_name,
con.[name] as constraint_name,
schema_name(t.schema_id) + ''.'' + t.[name] as [table],
col.[name] as column_name,
con.[definition],
case when con.is_disabled = 0
then ''Active''
else ''Disabled''
end as [status]
from sys.check_constraints con
left outer join sys.objects t
on con.parent_object_id = t.object_id
left outer join sys.all_columns col
on con.parent_column_id = col.column_id
and con.parent_object_id = col.object_id;
';
PRINT #sql;
EXEC sp_MSforeachdb #sql;
SELECT * FROM #results;

List all tables used in a SQL statement

Currently i have to create a list of all tables & schemes used in several (terribly) long SQL statements.
Of course i could go manually through the SQL statements and write down every table used in a JOIN, Subselect and so on.
But i'd be curious if there is any easier way to do it. maybe with a "simple" SQL statement, but i have no clue how to do it.
Why am i asking? I'd have to do this for about 50 SQL-Unload-Statements, where all of them use between 30 and 70 tables. I guess you can imagine this quite boring work
Thanks in advance for any input & hints!
Have a read here: How can i get the list of tables in the stored procedure
;WITH stored_procedures AS (
SELECT
o.name AS proc_name, oo.name AS table_name,
ROW_NUMBER() OVER(partition by o.name,oo.name ORDER BY o.name,oo.name) AS row
FROM sysdepends d
INNER JOIN sysobjects o ON o.id=d.id
INNER JOIN sysobjects oo ON oo.id=d.depid
WHERE o.xtype = 'P')
SELECT proc_name, table_name FROM stored_procedures
WHERE row = 1
ORDER BY proc_name,table_name
All credit to the OP of the code above in the thread above.
I will post this answer & mark it as solved, as it was the best and easiest way to solve my issue.
Hint was in a comment by #whereisSQL (thanks a lot!)
Seems like it was already asked in this thread, but i didn't find it:
https://dba.stackexchange.com/questions/121346/need-to-get-identify-all-tables-and-columns-in-a-sql-query/121355#121355
There is an online "get table column" tool to list the tables of a SQL statement here:
http://107.170.101.241:8080/getTableColumn/
It lists all tables and additionally columns used in the statement! Perfect solution in my case.
This may help. Using DMVs
IF EXISTS (
SELECT *
FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[sp_dependsobj]')
AND type IN (
N'P'
,N'PC'
)
)
DROP PROCEDURE [dbo].[sp_dependsobj]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[sp_dependsobj] (#Objname NVARCHAR(2000))
AS
BEGIN
SET NOCOUNT ON
DECLARE #ObjID INTEGER
DECLARE #ObjType VARCHAR(100)
DECLARE #RowCount INTEGER = 0
SELECT #ObjID = OBJECT_ID(#Objname)
SELECT #ObjType = TYPE
FROM sys.objects
WHERE object_id = #ObjID
DECLARE #RefObjects AS TABLE (
[Object_name] SYSNAME
,[Type] VARCHAR(255)
,referenced_entity_name SYSNAME
,Column_name SYSNAME NULL
,referenced_entity_type VARCHAR(255)
)
DECLARE #FoundIn AS TABLE (
[Object_name] SYSNAME
,[Found In] SYSNAME
,[Type] VARCHAR(255)
)
DECLARE #SQLStr VARCHAR(MAX)
SET #SQLStr = '
WITH CTE_Objects
AS
(
SELECT o.NAME referencing_entity_name
,o.type_desc referencing_object_type
,sed.referenced_entity_name
,refobj.referenced_minor_name
,obj.type_desc
,obj.object_id
FROM sys.sql_expression_dependencies sed
INNER JOIN sys.objects o ON sed.referencing_id = o.[object_id]
INNER JOIN sys.objects obj ON sed.referenced_entity_name = obj.name
INNER JOIN sys.dm_sql_referenced_entities(''dbo.' + #Objname + ''', ''OBJECT'') refobj ON
refobj.referenced_id = sed.referenced_id
WHERE o.NAME = ''' + #Objname + '''
UNION
SELECT ''' + #Objname + ''', (SELECT type_desc from sys.objects where name = ''' + #Objname + '''), referenced_entity_name, NULL, obj.type_desc
,obj.object_id
FROM sys.dm_sql_referenced_entities (''dbo.' + '' + #Objname +
''', ''OBJECT'') refObj INNER JOIN sys.objects obj
ON refObj.referenced_entity_name = obj.name
)
SELECT CTE.referencing_entity_name Object_name, CTE.referencing_object_type Type, CTE.referenced_entity_name, CTE.referenced_minor_name Column_name, CTE.type_desc referenced_entity_type
FROM CTE_Objects CTE LEFT JOIN sys.columns cl ON
cte.object_id = cl.object_id AND cte.referenced_minor_name = cl.name
Order by cte.referencing_entity_name, CASE WHEN cte.referencing_entity_name IS NULL THEN 0 ELSE cl.column_id END
'
INSERT INTO #RefObjects (
[Object_name]
,[Type]
,referenced_entity_name
,Column_name
,referenced_entity_type
)
EXEC (#SQLStr)
SET #RowCount = ##ROWCOUNT
IF #RowCount > 0
BEGIN
SELECT *
FROM #RefObjects
END
SET #SQLStr = '
SELECT DISTINCT [Object Name] = o.NAME
,[Found In] = sp.NAME
,sp.type_desc Type
FROM sys.objects o
INNER JOIN sys.sql_expression_dependencies sd ON o.object_id = sd.referenced_id
INNER JOIN sys.objects sp ON sd.referencing_id = sp.object_id
WHERE o.NAME = ''' + #Objname + '''
UNION
SELECT ''' + #Objname + ''', referencing_entity_name, (SELECT type_desc from sys.objects where name = referencing_entity_name)
FROM sys.dm_sql_referencing_entities (''dbo.' + '' + #Objname + ''', ''OBJECT'');
'
INSERT INTO #FoundIn (
[Object_name]
,[Found In]
,[Type]
)
EXEC (#SQLStr)
SET #RowCount = ##ROWCOUNT
IF #RowCount > 0
BEGIN
SELECT *
FROM #FoundIn
END
IF NOT EXISTS (
SELECT 1
FROM #RefObjects
)
AND NOT EXISTS (
SELECT 1
FROM #FoundIn
)
BEGIN
PRINT 'Object does not reference any object, and no objects reference it.'
END
SET NOCOUNT OFF
END
GO
The question is old, but here is a regex for those that want the tables used in SQL statement (From/join).
I created it specially for my case, but it may be adapt and useful for others:
(from|join)[ ]{1,}[^.\n\ ]+?(?=(.))[.].*?(?=( |\n))

How to adjust TSQL code to truncate only tables of the dim schema?

I have the following to modify..
DECLARE #tablename AS VARCHAR (1000)
DECLARE #sql AS VARCHAR (1000)
IF OBJECT_ID('tempdb.dbo.#tables') IS NOT NULL
DROP TABLE #tables
SELECT *
INTO #tables
FROM sys.tables
WHILE EXISTS (SELECT *
FROM #tables)
BEGIN
SELECT #tablename = name
FROM #tables
SELECT #sql = 'truncate table ' + #tablename;
PRINT #sql
EXECUTE (#sql)
DELETE #tables
WHERE name = #tablename;
END
The above code will truncate all tables in a database, which is what I need however I only want this to work on tables that are part of the "dim" schema.
As an example, I have the following tables..
dbo.sales
dim.employee
dim.office
I'd like the script to only truncate the "dim" schema tables and not the dbo.sales table.
This is assuming that I don't have any PK/FK (as I have another code handling the drop/create of PK/FK).
Any help would be appreciated.
Thanks.
Try this one -
Query:
DECLARE #SQL NVARCHAR(MAX) = ''
SELECT #SQL = (
SELECT 'TRUNCATE TABLE [' + s.name + '].[' + o.name + ']' + CHAR(13)
FROM sys.objects o WITH (NOWAIT)
JOIN sys.schemas s WITH (NOWAIT) ON o.[schema_id] = s.[schema_id]
WHERE o.[type] = 'U'
AND s.name = 'dim'
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')
PRINT #SQL
EXEC sys.sp_executesql #SQL
Output:
TRUNCATE TABLE [dim].[test1]
TRUNCATE TABLE [dim].[test2]
TRUNCATE TABLE [dim].[test3]
TRUNCATE TABLE [dim].[test4]
...
SELECT SCHEMA_NAME(schema_id) + '.' + name as name
INTO #tables
FROM sys.tables
where SCHEMA_NAME(schema_id) = 'dim'

Wipe out all data in a scheme, leave structure intact

We're going to be going through a period of testing on a product soon. This product is a web application with a SQL Server 2008R2 backend.
Our database has several schemas within it (Customer, DataEntry, and a few others).
I have found ways to wipe all data in a database without breaking referential integrity or the data structures, which is close to what we're looking to do. The problem I'm finding is that we actually need a bunch of the data from some of the tables. Essentially, we only want to wipe the Customers schema.
We have a script written which will load in the test data for customers, but is there a way to change the techniques in my linked article to target only a specific schema? Is there a better way to clear all data in a schema?
A common scenario for me as well. I usually write what I call a reset script, deleting all data form the target tables in the order necessary to prevent referential errors, and then reseed the primary keys.
DELETE FROM < table 1 >
DELETE FROM < table 2 >
... etc ...
DBCC CHECKIDENT (< table 1 >, RESEED, 0)
DBCC CHECKIDENT (< table 2 >, RESEED, 0)
... etc ...
EDIT
To more fully answer the original question. to leave data in specific tables you would need to modify the block of code that does the deleting / truncating, and also modify the code that reseeds the idents in a similar way.
EXEC sp_MSForEachTable '
IF object_id(''?'') != < table name > AND object_id(''?'') != < table name > AND ... etc ...
BEGIN
IF OBJECTPROPERTY(object_id(''?''), ''TableHasForeignRef'') = 1
DELETE FROM ?
ELSE
TRUNCATE TABLE ?
END
'
GO
Just set the #schemaID to the name of the schema you wish to blow away and it should do the rest. If you end up with a FK dependency loop it will break and tell you what to do...
Declare #schemaID Nvarchar(256)
Set #schemaID = 'Schema' -- Set this to the name of the schema you wish to blow away
If Object_ID('tempdb..#tables') Is Not Null Drop Table #tables
Create Table #tables (tID Int, SchemaName Nvarchar(256), TableName Nvarchar(256))
Insert #tables
Select Row_Number() Over (Order By s.name, so.name), s.name, so.name
From sysobjects so
Join sys.schemas s
On so.uid = s.schema_id
Where so.xtype = 'u'
And s.name = #schemaID
Declare #SQL Nvarchar(Max),
#schema Nvarchar(256),
#table Nvarchar(256),
#iter Int = 1,
#loopCatch Int = 0
While Exists (Select 1
From #tables)
Begin
Select #schema = SchemaName,
#table = TableName
From #tables
Where tID = #iter
If Exists (Select 1
From sysobjects o
Join sys.schemas s1
On o.uid = s1.schema_id
Join sysforeignkeys fk
On o.id = fk.rkeyid
Join sysobjects o2
On fk.fkeyid = o2.id
Join sys.schemas s2
On o2.uid = s2.schema_id
Join #tables t
On o2.name = t.TableName Collate Database_Default
And s2.name = t.SchemaName Collate Database_Default
Where o.name = #table
And s1.name = #schema)
Begin
Update t
Set tID = (Select Max(tID) From #tables) + 1
From #tables t
Where tableName = #table
And schemaName = #schema
Set #iter = #iter + 1
End
Else
Begin
Set #Sql = 'Truncate Table [' + #schema + '].[' + #table + ']'
Begin Try
Exec sp_executeSQL #SQL;
Delete t
From #tables t
Where tableName = #table
And schemaName = #schema
Set #iter = #iter + 1
End Try
Begin Catch
Print #SQL
Update t
Set tID = (Select Max(tID) From #tables) + 1
From #tables t
Where tableName = #table
And schemaName = #schema
Set #iter = #iter + 1
Set #loopCatch = #loopCatch + 1;
If #loopCatch > 5
Begin
Select 'WARNING: Endless FK redundancy loop. Drop the constraints and these tables, truncate and reapply constraints manually'
Union All
Select '[' + SchemaName + '].[' + TableName + ']'
From #tables;
Break;
End
End Catch
End
End
This is parameterized on database and schema. If no schema is supplied, it will clear all data in the specified database.
Handles tables with foreign key references appropriately by disabling constraints. If the procedure fails, which it shouldn't normally do, ensure that you run it successfully after fixing the cause of the problem, which should ensure constraint checking goes back to normal.
This will not handle foreign key references correctly if you have foreign keys between schemas, however, it could be fairly easily amended to handle this.
create procedure [removeData] (#database_name sysname, #schema_name sysname = null)
as
set nocount on
create table #tables (
TableName varchar(900) not null primary key,
HasFKRef bit not null
);
declare #sql nvarchar(4000),
#table_name varchar(900);
if (db_id(#database_name) is null)
raiserror ('You must at least specify the database name', 16, 1);
set #sql = 'select ''['' + TABLE_CATALOG + ''].['' + TABLE_SCHEMA + ''].['' + TABLE_NAME + '']'' as TableName, (case when exists(select * from [' + #database_name + '].INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc inner join [' + #database_name + '].INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc on rc.UNIQUE_CONSTRAINT_CATALOG = tc.CONSTRAINT_CATALOG and rc.UNIQUE_CONSTRAINT_SCHEMA = tc.CONSTRAINT_SCHEMA and rc.UNIQUE_CONSTRAINT_NAME = tc.CONSTRAINT_NAME where tc.TABLE_NAME = t.TABLE_NAME) then 1 else 0 end) as HasFKRef
from [' + #database_name + '].INFORMATION_SCHEMA.TABLES t
where TABLE_TYPE = ''BASE TABLE'' and TABLE_SCHEMA = isnull(#schema_name, TABLE_SCHEMA)';
insert into #tables
exec sp_executesql #sql, N'#schema_name sysname', #schema_name;
declare #curse cursor
set #curse = cursor fast_forward for
select sql from (
select 'alter table ' + TableName + ' nocheck constraint all' as sql, 1 as sort
from #tables
union all
select 'truncate table ' + TableName, 2 as sort
from #tables
where HasFKRef = 0
union all
select 'delete from ' + TableName, 3 as sort
from #tables
where HasFKRef = 1
union all
select 'alter table ' + TableName + ' with check check constraint all', 4 as sort
from #tables
) t
order by sort, sql
open #curse
fetch next from #curse into #sql
while (##fetch_status = 0)
begin
exec (#sql)
fetch next from #curse into #sql
end
close #curse
GO

Resources