변수 인 테이블 이름


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]

내가 쉽게 원하기 때문에하는 것은 그쪽 이름을 변경 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에 이미 있는지 확인하고 있으면 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

3
그러나 그러한 쿼리에서 값을 반환하는 방법은 무엇입니까? 예를 들어 COUNT(*)?
Suncatcher

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
스택 오버플로에 오신 것을 환영합니다! 이 코드가 문제를 해결하는 방법과 이유에 대한 설명포함 하여 질문을 해결할 수는 있지만 게시물의 품질을 향상시키는 데 도움이되고 더 많은 투표를 할 수 있습니다. 지금 질문하는 사람 만이 아니라 앞으로 독자들에게 질문에 대답하고 있음을 기억하십시오. 제발 편집 설명을 추가하고 제한 및 가정이 적용 무엇의 표시를 제공하는 답변을. 검토에서
이중 신호음

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.