変数としてのテーブル名


171

私はこのクエリを実行しようとしています:

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

これにより、次のエラーが発生します。

メッセージ1087、レベル16、状態1、行5

テーブル変数「@tablename」を宣言する必要があります。

テーブル名を動的に入力する正しい方法は何ですか?

回答:


131

質問のような静的クエリの場合、テーブル名と列名は静的である必要があります。

動的クエリの場合は、完全なSQLを動的に生成し、sp_executesqlを使用してそれを実行する必要があります。

これは、異なるデータベースの同じテーブル間でデータを比較するために使用されるスクリプトの例です。

静的クエリ:

SELECT * FROM [DB_ONE].[dbo].[ACTY]
EXCEPT
SELECT * FROM [DB_TWO].[dbo].[ACTY]

私はしたいので、簡単のthaの名前を変更tableし、schema私はこのダイナミックなクエリを作成しました:

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の呪いと祝福


103

最後のステートメントを次のように変更します。

EXEC('SELECT * FROM ' + @tablename)

これが私がストアドプロシージャで行う方法です。最初のブロックは変数を宣言し、現在の年と月の名前に基づいてテーブル名を設定します(この場合はTEST_2012OCTOBER)。次に、それがすでにDBに存在するかどうかを確認し、存在する場合は削除します。次に、次のブロックは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''')

これが最良の答えです。
ColinMac

これは、OPの既存のコードに最も直接適用できるため、最良の答えです。
BH

37

答えには少し遅れますが、他の人を助ける必要があります:

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

15
QUOTENAMEはセキュリティにとって重要です。ありがとう。
Cihan Yakar、2015

3
しかし、そのようなクエリから値を返す方法は?例えばCOUNT(*)
サンキャッチャー2018

35

変数にテーブル名を使用することはできません。代わりにこれを行う必要があります。

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

14

SQLを動的に生成する必要があります。

declare @tablename varchar(50) 

set @tablename = 'test' 

declare @sql varchar(500)

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

exec (@sql)

8

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

この例は非常に便利です。
Downhillski

0

また、これを使用できます...

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

0
Declare  @tablename varchar(50) 
set @tablename = 'Your table Name' 
EXEC('select * from ' + @tablename)

1
Stack Overflowへようこそ!このコードは問題を解決する可能性がありますが、これが問題を解決する方法と理由の説明含めると、投稿の品質が向上し、おそらく投票数が増えることになります。あなたが今尋ねている人だけでなく、あなたが将来の読者のための質問に答えていることを忘れないでください。回答を編集して説明を追加し、適用される制限と前提を示してください。口コミから
ダブルビープ

0

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を実行する

EXEC sp_executesql @sql;

EXECUTE sp_executesqlを使用してSQLを実行する

EXECUTE sp_executesql @sql

-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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.