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:
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
Error 1045 (28000): Access Denied For User 'Root'@'Localhost' (Using Password: Yes)
Stored Procedure That Automatically Delete Rows Older Than 7 Days in MySQL
MySQL - Error 1045 - Access Denied
MySQL Fails On: MySQL "Error 1524 (Hy000): Plugin 'Auth_Socket' Is Not Loaded"
Error: Tcp Provider: Error Code 0X2746. During the SQL Setup in Linux Through Terminal
Dplyr Left_Join by Less Than, Greater Than Condition
Pass R Variable to Rodbc'S Sqlquery
Error Installing MySQL2: Failed to Build Gem Native Extension
Gem Install: Failed to Build Gem Native Extension (Can't Find Header Files)
"193: %1 Is Not a Valid Win32 Application" Bug With a New Rails Application
How to Delete Duplicate Records in MySQL Database
Rails 4 Like Query - Activerecord Adds Quotes
What the Difference Between MySQL and MySQL2 Gem
Error When Trying to Install App With MySQL2 Gem
Correct MySQL Configuration For Ruby on Rails Database.Yml File
Rails 3 Query on Condition of an Association'S Count