2010-05-15 63 views
106

我试图执行这个查询:表名作为变量

declare @tablename varchar(50) 
set @tablename = 'test' 
select * from @tablename 

这将产生以下错误:

Msg 1087, Level 16, State 1, Line 5

Must declare the table variable "@tablename".

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

回答

91

表名和列名必须是静态的,如果查询是静态的。对于动态表名或列名,应该动态生成完整的SQL,并使用sp_executesql执行它。

更多细节在这里:The curse and blessings of dynamic SQL

31

不能为一个变量使用一个表名,你不得不这样做,而不是:

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

你需要动态地生成SQL:

declare @tablename varchar(50) 

set @tablename = 'test' 

declare @sql varchar(500) 

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

exec (@sql) 
59

你的最后一条语句改成这样:

EXEC('SELECT * FROM ' + @tablename) 

这是我做我的在一个存储过程中。第一个块将声明该变量,并根据当前年份和月份名称设置表名,在这种情况下为TEST_2012OCTOBER。然后我检查它是否已经存在于数据库中,并且如果它确实存在,则将其删除。然后下一个块将使用一个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''') 
26

有点晚了一个答案,但应该帮忙别人:

CREATE PROCEDURE [dbo].[GetByName] 
    @TableName NVARCHAR(100) 
    AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 
    DECLARE @sSQL nvarchar(500); 

    SELECT @sSQL = N'SELECT * FROM' + QUOTENAME(@TableName); 

    EXEC sp_executesql @sSQL 



END 
+6

QUOTENAME是安全的重要线路。谢谢。 – 2015-04-28 10:05:43

+0

但是如何从这样的查询返回值?例如。 'COUNT(*)'? – Suncatcher 2018-03-03 09:57:12

-1
Declare @fs_e int, @C_Tables CURSOR, @Table varchar(50) 

SET @C_Tables = CURSOR FOR 
     select name from sysobjects where OBJECTPROPERTY(id, N'IsUserTable') = 1 AND name like 'TR_%' 
OPEN @C_Tables 
FETCH @C_Tables INTO @Table 
    SELECT @fs_e = sdec.fetch_Status FROM sys.dm_exec_cursors(0) as sdec where sdec.name = '@C_Tables' 

WHILE (@fs_e <> -1) 
    BEGIN 
     exec('Select * from '+ @Table) 
     FETCH @C_Tables INTO @Table 
     SELECT @fs_e = sdec.fetch_Status FROM sys.dm_exec_cursors(0) as sdec where sdec.name = '@C_Tables' 
    END 
1
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 

我已经把是p

+0

这篇文章需要编辑,可能需要一些解释.. – 2017-07-25 12:15:49