2010-05-15 19 views
106

ich diese Abfrage auszuführen versuchen:Tabellenname als Variable

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

Dies erzeugt die folgenden Fehler:

Msg 1087, Level 16, State 1, Line 5

Must declare the table variable "@tablename".

Was ist der richtige Weg, Tabellennamen dynamisch bevölkerten haben?

Antwort

91

Tabellennamen und Spaltennamen statisch sein müssen, wenn die Abfrage ist statisch. Bei dynamischen Tabellen- oder Spaltennamen sollten Sie das vollständige SQL dynamisch generieren und es mit sp_executesql ausführen.

Weitere Details hier: The curse and blessings of dynamic SQL

31

Sie können nicht einen Tabellennamen für eine Variable verwenden, würden Sie diese stattdessen zu tun haben:

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

Sie werden die SQL dynamisch generieren müssen:

declare @tablename varchar(50) 

set @tablename = 'test' 

declare @sql varchar(500) 

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

exec (@sql) 
59

Ihre letzte Aussage zu dieser Änderung:

EXEC('SELECT * FROM ' + @tablename) 

Dies ist, wie ich meine zu tun in einer gespeicherten Prozedur. Der erste Block deklariert die Variable und legt den Tabellennamen basierend auf dem aktuellen Jahr- und Monatsnamen fest, in diesem Fall TEST_2012OCTOBER. Ich überprüfe dann, ob es bereits in der DB existiert, und entferne es, wenn es funktioniert. Dann verwendet der nächste Block eine SELECT INTO-Anweisung, um die Tabelle zu erstellen und sie mit Datensätzen aus einer anderen Tabelle mit Parametern zu füllen.

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

Bit spät für eine Antwort, aber sollte jemand anders helfen:

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 für die Sicherheit wichtig ist. Vielen Dank. –

+0

Aber wie man Wert von solcher Frage zurückbringt? Z.B. '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 

ich die Linien gesetzt haben, die p

+0

Dieser Beitrag muss bearbeitet werden und benötigt möglicherweise eine Erklärung. –