Sql 作为变量的表名

Sql 作为变量的表名,sql,sql-server,tsql,variable-names,tablename,Sql,Sql Server,Tsql,Variable Names,Tablename,我正在尝试执行此查询: declare @tablename varchar(50) set @tablename = 'test' select * from @tablename 这会产生以下错误: Msg 1087,16级,状态1,第5行 必须声明表变量“@tablename” 动态填充表名的正确方法是什么?变量不能使用表名。您必须这样做: DECLARE @sqlCommand varchar(1000) SET @sqlCommand = 'SELECT * from yourtab

我正在尝试执行此查询:

declare @tablename varchar(50)
set @tablename = 'test'
select * from @tablename
这会产生以下错误:

Msg 1087,16级,状态1,第5行

必须声明表变量“@tablename”


动态填充表名的正确方法是什么?

变量不能使用表名。您必须这样做:

DECLARE @sqlCommand varchar(1000)
SET @sqlCommand = 'SELECT * from yourtable'
EXEC (@sqlCommand)

对于静态查询(如问题中的查询),表名和列名需要是静态的

对于动态查询,您应该动态生成完整的SQL,并使用sp_executesql来执行它

下面是一个脚本示例,用于比较不同数据库的相同表之间的数据:

静态查询:

SELECT * FROM [DB_ONE].[dbo].[ACTY]
EXCEPT
SELECT * FROM [DB_TWO].[dbo].[ACTY]
由于我想轻松更改
模式
的名称,我创建了这个动态查询:

declare @schema varchar(50)
declare @table varchar(50)
declare @query nvarchar(500)

set @schema = 'dbo'
set @table = 'ACTY'

set @query = 'SELECT * FROM [DB_ONE].[' + @schema + '].[' + @table + '] EXCEPT SELECT * FROM [DB_TWO].[' + @schema + '].[' + @table + ']'

EXEC sp_executesql @query

由于动态查询有许多需要考虑的细节,而且很难维护,因此我建议您阅读:

您需要动态生成SQL内容:

declare @tablename varchar(50)

set @tablename = 'test'

declare @sql varchar(500)

set @sql = 'select * from ' + @tablename

exec (@sql)

将您的上一句话更改为:

EXEC('SELECT * FROM ' + @tablename)
这就是我在存储过程中的工作方式。第一个块将声明变量,并基于当前年份和月份名称设置表名,在本例中为TEST_2012ocoter。然后检查它是否已经存在于数据库中,如果存在则删除。然后,下一个块将使用SELECT INTO语句创建该表,并使用另一个带有参数的表中的记录填充该表

--DECLARE TABLE NAME VARIABLE DYNAMICALLY
DECLARE @table_name varchar(max)
SET @table_name =
    (SELECT 'TEST_'
            + DATENAME(YEAR,GETDATE())
            + UPPER(DATENAME(MONTH,GETDATE())) )

--DROP THE TABLE IF IT ALREADY EXISTS
IF EXISTS(SELECT name
          FROM sysobjects
          WHERE name = @table_name AND xtype = 'U')

BEGIN
    EXEC('drop table ' +  @table_name)
END

--CREATES TABLE FROM DYNAMIC VARIABLE AND INSERTS ROWS FROM ANOTHER TABLE
EXEC('SELECT * INTO ' + @table_name + ' FROM dbo.MASTER WHERE STATUS_CD = ''A''')
使用:

声明@fs_e int、@C_Tables CURSOR、@Table varchar(50)
设置@C_Tables=光标用于
从sysobjects中选择名称,其中OBJECTPROPERTY(id,N'IsUserTable')=1,名称类似于'TR\%'
打开@C_表
将@C_表提取到@Table中
从sys.dm_exec_游标(0)中选择@fs_e=sdec.fetch_Status作为sdec,其中sdec.name='@C_Tables'
而(@fs_e-1)
开始
exec('从'+@表中选择*)
将@C_表提取到@Table中
从sys.dm_exec_游标(0)中选择@fs_e=sdec.fetch_Status作为sdec,其中sdec.name='@C_Tables'
结束

使用
sp_executesql
执行任何SQL,例如

DECLARE @tbl    sysname,
        @sql    nvarchar(4000),
        @params nvarchar(4000),
        @count  int

DECLARE tblcur CURSOR STATIC LOCAL FOR
   SELECT object_name(id) FROM syscolumns WHERE name = 'LastUpdated'
   ORDER  BY 1
OPEN tblcur

WHILE 1 = 1
BEGIN
   FETCH tblcur INTO @tbl
   IF @@fetch_status <> 0
      BREAK

   SELECT @sql =
   N' SELECT @cnt = COUNT(*) FROM dbo.' + quotename(@tbl) +
   N' WHERE LastUpdated BETWEEN @fromdate AND ' +
   N'                           coalesce(@todate, ''99991231'')'
   SELECT @params = N'@fromdate datetime, ' +
                    N'@todate   datetime = NULL, ' +
                    N'@cnt      int      OUTPUT'
   EXEC sp_executesql @sql, @params, '20060101', @cnt = @count OUTPUT

   PRINT @tbl + ': ' + convert(varchar(10), @count) + ' modified rows.'
END

DEALLOCATE tblcur
DECLARE@tbl sysname,
@sql nvarchar(4000),
@params nvarchar(4000),
@计数整数
将tblcur游标声明为静态本地
从syscolumns中选择object_name(id),其中name='LastUpdated'
按1订购
开放式tblcur
而1=1
开始
将tblcur提取到@tbl中
如果@@fetch\u状态为0
打破
选择@sql=
N'从dbo中选择@cnt=COUNT(*)。+quotename(@tbl)+
N'在@fromdate和'+
联合(@todate,'99991231')”
选择@params=N'@fromdate-datetime,'+
N'@todate datetime=NULL,'+
N'@cnt int输出'
EXEC sp_executesql@sql,@params,@20060101',@cnt=@count输出
打印@tbl+':'+转换(varchar(10),@count)+“修改行”
结束
解除分配tblcur

此外,您还可以使用此

DECLARE @SeqID varchar(150);
DECLARE @TableName varchar(150);
SET @TableName = (Select TableName from Table);
SET @SeqID = 'SELECT NEXT VALUE FOR ' + @TableName + '_Data'
exec (@SeqID)

您需要使用SQL Server动态SQL:

DECLARE @table     NVARCHAR(128),
        @sql       NVARCHAR(MAX);

SET @table = N'tableName';

SET @sql = N'SELECT * FROM ' + @table;

使用EXEC执行任何SQL:

EXEC (@sql)
EXEC sp_executesql @sql;
EXECUTE sp_executesql @sql
使用EXEC sp_executesql执行任何SQL:

EXEC (@sql)
EXEC sp_executesql @sql;
EXECUTE sp_executesql @sql
使用执行sp_executesql执行任何SQL:

EXEC (@sql)
EXEC sp_executesql @sql;
EXECUTE sp_executesql @sql

QUOTENAME对安全性很重要。谢谢。但是如何从这样的查询中返回值呢?例如,
COUNT(*)
?@Suncatcher您可以拥有一个输出参数或将其作为结果集返回。要显示如何将其读入变量中,并且由于注释发布限制而不在变量上引入“at”符号:declare nCount int Exec('select nCount=count(*)from'+sTableName)这个例子非常有用。这是最好的答案。这是最好的答案,因为它最直接适用于OP的现有代码。欢迎使用堆栈溢出!虽然这段代码可以解决这个问题,但如何以及为什么解决这个问题将真正有助于提高您的帖子质量,并可能导致更多的投票。请记住,你是在将来回答读者的问题,而不仅仅是现在提问的人。请在回答中添加解释,并说明适用的限制和假设。我喜欢这个答案的简单性,它有着与问题地址相同的3行。我认为不需要解释。谢谢。将对象名称组合到动态SQL语句中时的最佳做法是避免出现奇数名称问题,例如带有空格的
New Table
或类似
From
的保留字。