Search code examples
sqlsql-servert-sql

Dynamic sql script to generate list of drop table statement


I've list of tables (around 100++) that need to be dropped from SQL Server. Below is the sample code that I would use

IF OBJECT_ID('dbo.DS_Area_TBL', 'U') IS NOT NULL
drop table dbo.DS_Area_TBL
Print 'dbo.DS_Area_TBL has been dropped'

I need to replace table name 100++ time with other table name. How to write a dynamic sql script that can auto generate list of queries?


Solution

  • You could first generate script then execute with dynamic sql:

    CREATE TABLE a(a INT);
    CREATE TABLE b(a INT);
    CREATE TABLE c(a INT);
    CREATE TABLE d(a INT);
    CREATE TABLE e(a INT);
    
    CREATE TABLE tab(tab_name SYSNAME);   -- here are table names stored
    INSERT INTO tab VALUES ('a'),('b'),('c'),('d'),('e');
    
    
    -- main part
    DECLARE @sql NVARCHAR(MAX);
    
    SELECT @sql = STUFF((SELECT ' ' +  FORMATMESSAGE(
    'IF OBJECT_ID(''%s'', ''U'') IS NOT NULL 
    BEGIN
       DROP TABLE %s;
       PRINT ''%s has been dropped '';
    END
    ', QUOTENAME(tab_name),QUOTENAME(tab_name),QUOTENAME(tab_name))
                       FROM tab
                       FOR XML PATH('')), 1, 1, '');
    
    PRINT @sql;   -- for debug
    
    EXEC [dbo].[sp_executesql]
        @sql;
    

    If you use version of SQL Server lower than 2012 you need to change FORMATMESSAGE with string concatenation +.

    You could easily extend this script with custom schema and so on by modifying template:

    'IF OBJECT_ID(''%s'', ''U'') IS NOT NULL 
        BEGIN
           DROP TABLE %s;
           PRINT ''%s has been dropped '';
        END
    '
    

    Output:

    IF OBJECT_ID('[a]', 'U') IS NOT NULL 
    BEGIN
       DROP TABLE [a];
       PRINT '[a] has been dropped ';
    END
     IF OBJECT_ID('[b]', 'U') IS NOT NULL 
    BEGIN
       DROP TABLE [b];
       PRINT '[b] has been dropped ';
    END
     IF OBJECT_ID('[c]', 'U') IS NOT NULL 
    BEGIN
       DROP TABLE [c];
       PRINT '[c] has been dropped ';
    END
     IF OBJECT_ID('[d]', 'U') IS NOT NULL 
    BEGIN
       DROP TABLE [d];
       PRINT '[d] has been dropped ';
    END
     IF OBJECT_ID('[e]', 'U') IS NOT NULL 
    BEGIN
       DROP TABLE [e];
       PRINT '[e] has been dropped ';
    END
    

    EDIT:
    How it works:

    1. XML + STUFF for string concatenation is common idiom with SQL Server, works like GROUP_CONCAT in MySQL. You can think about it as a way to combine multiple IF BEGIN END chunks into one string.
    2. FORMATMESSAGE will replace %s with actual table names(quoted to avoid SQL Injection attacks)
    3. PRINT is for debug to check generated query, can be commented
    4. sp_executesql will execute SQL string