-4

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

.
.
.
asmgx
  • 7,328
  • 15
  • 82
  • 143

2 Answers2

3

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)
David Browne - Microsoft
  • 80,331
  • 6
  • 39
  • 67
  • 5
    Usage note: the use of quotename prevents silly errors and mitigates SQL injection even though raw text is added to the query. – user2864740 Dec 27 '21 at 01:33
3

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.

user2864740
  • 60,010
  • 15
  • 145
  • 220