2

What is the best way to remove all the data from all the tables except look-up tables data using TSQL in SQL Server 2012 and downwards? I would like the TSQL identify and exclude look-up tables then create truncate table statements for the other tables.

** There is almost a similar question but it truncates all the tables.

Community
  • 1
  • 1
TheStudent
  • 21
  • 1
  • 5
  • 1
    What in your opinion make look-up tables different than other tables?. Do they have patterns in their names? If you can't figure out a manual way to differentiate between them, then the script won't. – BICube May 21 '15 at 21:41
  • Say we defined our constraints using [FK_Parent_Child] name standard. i.e. ALTER TABLE [dbo].[Parent] WITH CHECK ADD CONSTRAINT [FK_Parent_Child] FOREIGN KEY([TypeID]) REFERENCES [dbo].[Child] ([ID]) – TheStudent May 21 '15 at 22:26
  • @TheDot when you are deleting from a database I personally would be so hesitant to say, say we defined. You are still making assumptions and not sure how to differentiate between your tables. You might have many other foreign keys for tables that you need. Foreign keys aren't always inducing relationships between lookuptables-real tables. – BICube May 21 '15 at 22:30
  • No it was not an assumption, it is exactly the way it is. I agree that "Foreign keys aren't always inducing relationships between lookuptables-realt tables" but in this case, that is the exact way the database has been designed. Also I changed my ID to TheStudent, sorry about that. – TheStudent May 21 '15 at 22:45
  • This is a test database so there is nothing to worry about. – TheStudent May 21 '15 at 22:52
  • If the table is referenced by a FK then truncate will fail. So just truncate all the tables. – paparazzo May 22 '15 at 07:21
  • No, that is not the solution I am expecting – TheStudent May 22 '15 at 13:52

6 Answers6

0

Both Lookup Tables and non Lookup tables are similar in technical characteristics. Only functionally they are different. Hence there won't be specific criteria to differentiate both of them.

0

Unless you set yourself up to be able to do this from the design standpoint, e.g. putting all "Lookup" tables in a "lkup" schema, or something of that nature, I don't think there's a way to do this. As someone already mentioned, a lookup table is a table like any other.

Cortright
  • 1,164
  • 6
  • 19
0

I would automate using DELETE by deleting in the right order first of all (dependencies)

1) pass the table name

2) disable your foreign keys

3) empty DELETE ALL the table

4) re-enable they keys.

this way you can control passing the table names you want "truncated" with a conditional.

rrb6699
  • 1
  • 3
0

or will it matter then:

ALTER PROCEDURE 
up_ResetEntireDatabase 
@IncludeIdentReseed BIT, 
@IncludeDataReseed BIT 
AS 

EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL' 
EXEC sp_MSForEachTable 'DELETE FROM ?'

 IF @IncludeIdentReseed = 1 
BEGIN 
EXEC sp_MSForEachTable 'DBCC CHECKIDENT (''?'' , RESEED, 1)' 
END 

EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL' 

IF @IncludeDataReseed = 1 
BEGIN 
-- Populate Core Data Table Here 
END 

GO

And then once ready the execution is really simple:

EXEC up_ResetEntireDatabase 1, 1
Stephan
  • 5,891
  • 1
  • 16
  • 24
rrb6699
  • 1
  • 3
  • of course it matters, why else would i bother ask a question? your script deletes all the data from all the tables. I do not like this idea. – TheStudent May 21 '15 at 22:19
  • @rrg6699 it is recommended to edit an answer and add/subtract from it unless you mean for each post to be a completely different answer. – Stephan May 22 '15 at 00:41
  • @The Student, I only answered in general. you would have to add the code to your specific needs – rrb6699 May 22 '15 at 08:09
0

I'm not sure if you mean lookup tables like one that could drive this.

build a simple table that has names of each of the database tables and create columns you could modify if necessary before you execute the script.

the columns could just be flags that tell the script whether or not to truncate that table or other.

that way you (script) will know dependencies as it reads table names. an index is not needed if you keep table order static in record number order.

just another maintenance script.

rrb6699
  • 1
  • 3
  • No, this is not the approach I will use. There are all sort of information in system views. There is no point creating extra table! – TheStudent May 22 '15 at 14:30
0

So you want to truncate the tables that have foreign keys but keep the references tables alone. This should do it.

WITH CTE_fks
AS
(
    SELECT  obj.name AS FK_NAME,
            sch1.name AS [table_schema],
            tab1.name AS [table_name],
            col1.name AS [column],
            sch2.name AS [ref_table_schema],
            tab2.name AS [referenced_table],
            col2.name AS [referenced_column]
    FROM sys.objects obj
    INNER JOIN sys.foreign_key_columns fkc
        ON obj.object_id = fkc.constraint_object_id
    INNER JOIN sys.tables tab1
        ON tab1.object_id = fkc.parent_object_id
    INNER JOIN sys.schemas sch1
        ON tab1.schema_id = sch1.schema_id
    INNER JOIN sys.columns col1
        ON col1.column_id = parent_column_id AND col1.object_id = tab1.object_id
    INNER JOIN sys.tables tab2
        ON tab2.object_id = fkc.referenced_object_id
    INNER JOIN sys.schemas sch2
        ON tab2.schema_id = sch2.schema_id
    INNER JOIN sys.columns col2
        ON col2.column_id = referenced_column_id AND col2.object_id = tab2.object_id
)

SELECT  'TRUNCATE TABLE ' + QUOTENAME(A.TABLE_SCHEMA) + '.' + QUOTENAME(A.table_name) + ';'
FROM INFORMATION_SCHEMA.TABLES A
LEFT JOIN CTE_fks B
ON A.TABLE_NAME = B.referenced_table
AND A.TABLE_SCHEMA = B.ref_table_schema
WHERE A.TABLE_TYPE = 'BASE TABLE'
AND A.TABLE_NAME != 'sysdiagrams'
AND B.table_name IS NULL
Stephan
  • 5,891
  • 1
  • 16
  • 24
  • This script seems will work but could you complete the script so it return the database to it's original state (enable the foreign keys) so I can test it. By the way, I noticed the above script, it also generates `TRUNCATE TABLE [dbo].[sysdiagrams]` which I think should not be part of selected tables. – TheStudent May 22 '15 at 14:23
  • You can't re-enable the foreign keys because there's nothing in the look up tables. And just add a where clause to exclude sysdiagrams – Stephan May 22 '15 at 14:50
  • All the look up tables have value. They are not empty so we should be able to re-enable them. That's whole point of this question. To keep the data in look-up tables intact while deleting data from the rest of tables. – TheStudent May 22 '15 at 14:57
  • Oh I'm sorry. I got a little confused there. I see what you mean, and I don't think you'll need to disable the foreign keys. Let me edit my answer. – Stephan May 22 '15 at 21:00