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

Time:12-27

Using SQL Server

I have queries that use table name

Select *
from MyDB..Table1 A inner join MyDB..Table1 B ON A.ID = B.ParentID

SELECT * FROM MyDB..Table1 WHERE No > @X

.
.
.

and I have to run these queries for 10 tables

I don't want to discuss the architecture of the database

but this is the status quo

I want a way to make table name variable (if possible) and change it in one place instead of all places

@declare @T as Table = MyDB..Table1
Select *
from @T A inner join @T B ON A.ID = B.ParentID

SELECT * FROM @T WHERE No > @X

.
.
.

CodePudding user response:

You can't do this in static SQL, but it's trivial with dynamic SQL, eg

declare @T as sysname = 'Table1'

declare @sql nvarchar(max) = 'Select * from TableNamePlaceholder A inner join TableNamePlaceholder B ON A.ID = B.ParentID'
set @sql = replace(@sql,'TableNamePlaceholder',quotename(@T))
exec (@sql)

CodePudding user response:

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 of 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.

  • Related