Search code examples
sqlsql-servert-sqlvariable-namestablename

A table name as a variable


I am trying to execute this query:

declare @tablename varchar(50)
set @tablename = 'test'
select * from @tablename

This produces the following error:

Msg 1087, Level 16, State 1, Line 5

Must declare the table variable "@tablename".

What's the right way to have the table name populated dynamically?


Solution

  • For static queries, like the one in your question, table names and column names need to be static.

    For dynamic queries, you should generate the full SQL dynamically, and use sp_executesql to execute it.

    Here is an example of a script used to compare data between the same tables of different databases:

    Static query:

    SELECT * FROM [DB_ONE].[dbo].[ACTY]
    EXCEPT
    SELECT * FROM [DB_TWO].[dbo].[ACTY]
    

    Since I want to easily change the name of table and schema, I have created this dynamic query:

    declare @schema sysname;
    declare @table sysname;
    declare @query nvarchar(max);
    
    set @schema = 'dbo'
    set @table = 'ACTY'
    
    set @query = '
    SELECT * FROM [DB_ONE].' + QUOTENAME(@schema) + '.' + QUOTENAME(@table) + '
    EXCEPT
    SELECT * FROM [DB_TWO].' + QUOTENAME(@schema) + '.' + QUOTENAME(@table);
    
    EXEC sp_executesql @query
    

    Since dynamic queries have many details that need to be considered and they are hard to maintain, I recommend that you read: The curse and blessings of dynamic SQL