2010-05-15 7 views
106

Je suis en train d'exécuter cette requête:Nom de la table comme une variable

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

Cela produit l'erreur suivante:

Msg 1087, Level 16, State 1, Line 5

Must declare the table variable "@tablename".

Quelle est la bonne façon d'avoir le nom de la table de manière dynamique,?

Répondre

91

noms de table et les noms de colonnes doivent être statiques, si la requête est statique. Pour les noms de tables ou de colonnes dynamiques, vous devez générer dynamiquement le code SQL complet et utiliser sp_executesql pour l'exécuter.

Plus de détails ici: The curse and blessings of dynamic SQL

31

Vous ne pouvez pas utiliser un nom de table pour une variable, vous auriez à faire à la place:

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

Vous aurez besoin de générer dynamiquement sql:

declare @tablename varchar(50) 

set @tablename = 'test' 

declare @sql varchar(500) 

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

exec (@sql) 
59

Changer votre dernière déclaration à ceci:

EXEC('SELECT * FROM ' + @tablename) 

Voilà comment je fais le mien dans une procédure stockée. Le premier bloc déclare la variable et définit le nom de la table en fonction de l'année en cours et du nom du mois, dans ce cas TEST_2012OCTOBER. Je vérifie alors si elle existe déjà dans la base de données, et supprime si c'est le cas. Ensuite, le bloc suivant utilisera une instruction SELECT INTO pour créer la table et la remplir avec les enregistrements d'une autre table avec des paramètres.

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

peu en retard pour une réponse, mais devrait aider quelqu'un d'autre:

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 est important pour la sécurité. Merci. –

+0

Mais comment retourner une valeur à partir d'une telle requête? Par exemple. 'COUNT (*)'? – Suncatcher

-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 

J'ai mis les lignes p

+0

Ce message doit être modifié et peut avoir besoin d'explications. –

Questions connexes