A Table Name as a Variable

A table name as a variable

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

Use of variable table name in Query

You'll need to use Dyanmic SQL.
Dynamic SQL is simply that you build your query "dynamically" in a string either in your SQL procedure or in an application, and then you execute that string.

For example;

DECLARE @tableVar1 VARCHAR(255) = 'T_Atable1'
DECLARE @tableVar2 VARCHAR(255) = 'T_Atable2'
DECLARE @tableVar3 VARCHAR(255) = 'T_Atable3'


EXEC('
SELECT * FROM ' + @tableVar1 + '
WHERE ref IN (SELECT ref FROM ' + @tableVar2 + ')
AND customer IN (SELECT customer FROM ' + @tableVar3 + ')
')

Dynamic table name and variable name in query in SQL Server

Use sp_executesql and parameters:

DECLARE @table_name VARCHAR(50) = 'table_name';
DECLARE @valid_to datetime = getdate();

DECLARE @sql NVARCHAR(max) = N'
UPDATE '+ @table_name + N'
SET valid_flag = 0,
valid_to = @valid_to
WHERE valid_flag = 1
';

EXEC sp_executesql @sql, N'@valid_to datetime', @valid_to=@valid_to;

EDIT:

As recommended by Larnu a comment:

DECLARE @table_name sysname = 'table_name';
DECLARE @valid_to datetime = getdate();

DECLARE @sql NVARCHAR(max) = N'
UPDATE '+ QUOTENAME(@table_name) + N'
SET valid_flag = 0,
valid_to = @valid_to
WHERE valid_flag = 1
';

EXEC sp_executesql @sql, N'@valid_to datetime', @valid_to=@valid_to;

Create a table using a variable as the table name

You can use dynamic TSQL:

DECLARE @INSFIRSTNAME VARCHAR (100) = 'Ted'
DECLARE @INSSURNAME VARCHAR (100) = 'Smith'
DECLARE @INSSTAFFNO VARCHAR (10) = 'AB123'
DECLARE @INSYEAR VARCHAR (10) = '2018'
DECLARE @TABLENAME VARCHAR (400) = 'Timesheet_' + @INSFIRSTNAME + @INSSURNAME + @INSSTAFFNO + '_' + @INSYEAR

--declare a variable that will hold your query
declare @sql_create nvarchar(max)

--create the query concatenating DDL instructions and variables
set @sql_create=''
set @sql_create= @sql_create + 'CREATE TABLE ' + @TABLENAME
set @sql_create= @sql_create + ' (INSFIRSTNAME VARCHAR (100),'
set @sql_create= @sql_create + ' INSSURNAME VARCHAR (100),'
set @sql_create= @sql_create + ' INSSTAFFNO VARCHAR (10),'
set @sql_create= @sql_create + ' INSYEAR VARCHAR (10));'

set @sql_create= @sql_create + ' INSERT INTO ' + @TABLENAME
set @sql_create= @sql_create + ' (INSFIRSTNAME, INSSURNAME, INSSTAFFNO, INSYEAR)'
set @sql_create= @sql_create + ' VALUES ('''+@INSFIRSTNAME+''','''+ @INSSURNAME + ''','''+ @INSSTAFFNO+ ''',''' + @INSYEAR + ''')'

--execute the query contained inside the variable
exec sp_executesql @sql_create

Now you can select from your table:

Sample Image

is there a way to make table name as variable in sql server?

Not directly. One option that works well for SELECT queries is to create a view:

CREATE VIEW allTables (name, a, b)
AS
SELECT 'Table1' as name, a, b
FROM Table1
UNION ALL
SELECT 'Table2' ..

-- with constant; same as writing SELECT a, b FROM Table2
SELECT a, b
FROM allTables
WHERE name = 'Table2'

-- with variable; without PEO, all tables in QP even if not accessed
SELECT a, b
FROM allTables
WHERE name = @T
-- OPTION (RECOMPILE) -- get PEO, at expense of recompilation

SQL Server will entirely optimize out the non-relevant UNION ALL cases if PEO or constant folding applies, as if the UNION ALL branches did not even exist in the view / query at all!

Even without PEO, tables will only be queried if the name matches as SQL Server will eliminate 'non reachable' UNION ALL branches during execution. However this filter is applied during query execution and the tables are still included in the query plan. (Sometimes this can lead to odd plans if all the tables don’t have the identical favored indices.)

Unfortunately, this approach has limitations with DML (eg. view is non-updatable) and for DML I’ve found dynamic SQL, as shown in the other answer, to work well.

How to DEFINE a table NAME as a @variable and SELECT it

Try this.

DECLARE @TableName VARCHAR(20) = 'your_table_name'
DECLARE @sqlCommand VARCHAR(1000)
SET @sqlCommand = 'SELECT * from tbl_' + @TableName
EXEC (@sqlCommand)


Related Topics



Leave a reply



Submit