Is there a way to specify table name as a string?

前端 未结 3 1167
一生所求
一生所求 2020-12-19 09:51

Let us say I have a query like this:

SELECT * FROM 
(
  SELECT * FROM 
  (
    SELECT * FROM DB.dbo.Table
  )
  INNER JOIN DB.dbo.Table ON ...
相关标签:
3条回答
  • 2020-12-19 10:36

    No. Just as you cannot specify the function name in your c# program as a string. T-SQL compilation is supposed to come up with a precise access plan, meaning what indexes to open and use to satisfy the query. It would be impossible to come up with a plan for a 'string', just as it would be impossible in C# to generate the code to invoke a 'string' as a method.

    The solution is dynamic SQL:

    declare @sql NVARCHAR(MAX) = N'SELECT ... FROM ' +
       quotename(@dbname) + N'.' + quotename(@schema) + N'.' + quotename(@table) + 
       N' WHERE ...';
    exec sp_executesql @sql;
    

    ... just as in C# you would use reflection to do dynamic runtime invocation.

    For more info see The Curse and Blessings of Dynamic SQL.

    PS. the split of @tablename into components and the use of QUOTENAME is an absolute must, it guards agaisnt SQL Injection. Use PARSENAME to do the split for you.

    0 讨论(0)
  • 2020-12-19 10:39

    You can wrap it in an EXEC statement like this:

    declare @my_tablename nvarchar(100) = 'mytable';
    exec('
    SELECT * FROM 
    (
      SELECT * FROM 
      (
        SELECT * FROM ' + @my_tablename + '
      )
      INNER JOIN ' + @my_tablename + ' ON ...'
    );
    

    But no, intellisense will not work in that scenario.

    If you know what your output will look like in advance, then you can declare a temp table to hold the results, and then you can access that without EXEC. You will have intellisense on the temp table.

    For example:

      --this must match whatever your SELECT is going to return
      CREATE TABLE #results(
        FIELD1 INT
       ,FIELD2 NVARCHAR(100)
       ,FIELD3 BIT
       );
    
    EXEC('
      INSERT INTO #results(field1,field2,field3)
      SELECT FIELD1,FIELD2,FIELD3 FROM ' + @my_tablename
    );
    
    select * from #results  --you will have intellisense on #results
    
    0 讨论(0)
  • 2020-12-19 10:46

    You use dynamic SQL. Not sure why you need so many nested SELECTs but it would be something like:

    DECLARE @sql NVARCHAR(MAX) = N'SELECT ... FROM ' + @tablename + '...';
    EXEC sp_executeSQL @sql;
    

    However please be aware of SQL injection. And no, IntelliSense has no ability to parse a string for object names (or to even know while editing what object name is going to be there).

    0 讨论(0)
提交回复
热议问题