SQL Server SELECT INTO @variable?


250

Sql (2008) Stored Procs 중 하나에 다음 코드가 완벽하게 실행됩니다.

    CREATE PROCEDURE [dbo].[Item_AddItem]
        @CustomerId uniqueidentifier,
        @Description nvarchar(100),
        @Type int,
        @Username nvarchar(100),
    AS
    BEGIN

        DECLARE @TopRelatedItemId uniqueidentifier;
        SET @TopRelatedItemId = 
        (
           SELECT top(1) RelatedItemId 
           FROM RelatedItems 
           WHERE CustomerId = @CustomerId
        ) 

        DECLARE @TempItem TABLE
        (
            ItemId uniqueidentifier,
            CustomerId uniqueidentifier,
            Description nvarchar(100),
            Type int,
            Username nvarchar(100),
            TimeStamp datetime
        );

        INSERT INTO Item
        OUTPUT INSERTED.* INTO @TempItem
        SELECT NEWID(), @CustomerId, @Description, @Type, @Username, GETDATE()

        SELECT
            ItemId,
            CustomerId,
            @TopRelatedItemId,
            Description,
            Type,
            Username,
            TimeStamp
        FROM
            @TempItem
END
GO

따라서 여러분에게 질문은 다음과 같은 라인을 따라 무언가를 할 수 있다는 것입니다.

DECLARE @TempCustomer TABLE
(
   CustomerId uniqueidentifier,
   FirstName nvarchar(100),
   LastName nvarchar(100),
   Email nvarchar(100)
);
SELECT 
    CustomerId, 
    FirstName, 
    LastName, 
    Email 
INTO 
    @TempCustomer 
FROM 
    Customer
WHERE 
    CustomerId = @CustomerId

다른 진술에서 메모리 의이 데이터를 재사용 할 수 있도록? SQL Server는 위의 문에 적합하지만 별도의 변수를 만들고 동일한 테이블에 대해 별도의 SELECT 문을 통해 각 변수를 초기화하고 싶지는 않습니다 ... UGH !!!

같은 테이블에 대해 여러 번 쿼리하지 않고도 행을 따라 무언가를 달성하는 방법에 대한 제안 사항이 있습니까?


1
"별도의 변수를 만들고 별도의 SELECT 문을 통해 각 변수를 초기화하려면"-왜 그렇게해야합니까? declare @t table당신이 그것을 다시해야하는 경우 한 번, 그리고하는 화재 DELETE @TempCustomer다시에 삽입하기 전에
RichardTheKiwi

답변:


204

.. INTO .. ​​테이블 변수를 선택할 수 없습니다. 가장 좋은 방법은 먼저 만든 다음 삽입하는 것입니다. 두 번째 스 니펫은

DECLARE @TempCustomer TABLE
(
   CustomerId uniqueidentifier,
   FirstName nvarchar(100),
   LastName nvarchar(100),
   Email nvarchar(100)
);
INSERT INTO 
    @TempCustomer 
SELECT 
    CustomerId, 
    FirstName, 
    LastName, 
    Email 
FROM 
    Customer
WHERE 
    CustomerId = @CustomerId

5
이것은 CTE 컨텍스트에서도 잘 작동합니다. 바 징가!
Michael Krauklis

4
실제 임시 테이블을 사용하여 가능한 것처럼 테이블 변수를 선택할 수없는 이유에 대한 답변이 있습니까?
KSwift87

504

나중에 사용하기 위해 일부 변수를 간단히 지정하려면 다음 행을 따라 한 번에 변수를 지정할 수 있습니다.

declare @var1 int,@var2 int,@var3 int;

select 
    @var1 = field1,
    @var2 = field2,
    @var3 = field3
from
    table
where
    condition

그것이 당신이 따르는 것의 유형이라면


1
최선의 답변 임도이지만 결과가 둘 이상인 경우 어떻게됩니까?
capitano666

결과가 둘 이상이면 사용 가능한 값 중 하나가 표시됩니다. 그것은 재미있는 퍼즐을 만들 수 있습니다! mssqltips.com/sqlservertip/1888/…
Smandoli

8
쿼리가 단일 행을 반환하도록하려면 SELECT TOP 1
Adrian

1
@Adrian 예, 위 쿼리는 단일 행을 선택한 것으로 가정합니다. 더 멋진 논리를 원하면 순서 지정 및 집계 함수를 사용할 수도 있습니다.
dougajmcdonald

1
OP가 사용하는 데이터베이스 유형을 사용하지 않는 경우 Adrian이 언급 한 것처럼 TOP 1을 모두 지원하지는 않습니다. SQL Server / MS 액세스는 TOP을 사용하고 MySQL은 LIMIT를 사용하며 Oracle은 ROWNUM을 사용합니다. 자세한 정보는 w3schools.com/sql/sql_top.asp 를 참조하십시오.
Tyler

33

당신은 이것을 할 수 있습니다 :

SELECT 
    CustomerId, 
    FirstName, 
    LastName, 
    Email
INTO #tempCustomer 
FROM 
    Customer
WHERE 
    CustomerId = @CustomerId

나중에

SELECT CustomerId FROM #tempCustomer

#tempCustomer의 구조를 선언 할 필요는 없습니다.


3
@webturner이 둘 중 어느 것도 사실이 아닙니다. 임시 테이블은 proc 외부에서 범위가 지정되지 않으며 테이블 변수는 임시 테이블보다 더 "메모리 만"이 아닙니다.
Martin Smith

7
더 이상 필요하지 않은 DROP TABLE #tempCustomer경우 를 추가하는 것을 잊지 마십시오. #tempCustomer그렇지 않으면 다음 선택에서 #tempCustomer already exists오류 가 발생합니다.
ViRuSTriNiTy

15

구문이 약간 벗어난 것 같습니다. 이것은 좋은 예가 있습니다

DECLARE @TempCustomer TABLE
(
   CustomerId uniqueidentifier,
   FirstName nvarchar(100),
   LastName nvarchar(100),
   Email nvarchar(100)
);
INSERT @TempCustomer 
SELECT 
    CustomerId, 
    FirstName, 
    LastName, 
    Email 
FROM 
    Customer
WHERE 
    CustomerId = @CustomerId

그런 다음 나중에

SELECT CustomerId FROM @TempCustomer

2

임시 테이블을 원하는 것처럼 들립니다. http://www.sqlteam.com/article/temporary-tables

#TempTable은 SP 전체에서 사용할 수 있습니다.

## TempTable은 모두 사용할 수 있습니다.


2
## TEMPTABLE - 소유자 (생성자)까지 그것을 삭제하거나 분리 얻는다
RichardTheKiwi

4
임시 테이블을 원하지 않습니다. 임시 테이블은 비싸고 느립니다. 특정 레코드에 대한 약간의 데이터를 짧은 시간 동안 유지하고 후속 조회없이 여러 SQL 문에서 사용할 수 있도록하고 싶습니다. 테이블 변수는 정의 된 저장 프로 시저 내에 범위가 있기 때문에 하나의 저장 프로 시저 호출에 대해 터플 된 데이터를 저장하기위한 완벽한 솔루션입니다.
bleepzter

3
또한 DB가 Azure에 상주한다고 언급하는 것을 잊어 버렸습니다. 임시 테이블 관리에서 혼란을 일으키고 싶지 않습니다.
bleepzter

변수 테이블은 갈 길입니다. @varTable 테이블 선언 (....)
ARLibertarian

1

귀하의 질문에 동일한 문제에 대한 해결책을 찾고 있습니다. 다른 답변이 지적하지 못하는 것은 변수를 사용하여 모든 프로 시저 실행에 대한 테이블 이름을 임시가 아닌 영구적 인 형식으로 변경하는 방법입니다.

지금까지 내가하는 일은 전체 SQL 코드를 사용할 변수와 연결하는 것입니다. 이처럼 :

declare @table_name as varchar(30)
select @table_name = CONVERT(varchar(30), getdate(), 112)
set @table_name = 'DAILY_SNAPSHOT_' + @table_name

EXEC('
        SELECT var1, var2, var3
        INTO '+@table_name+'
        FROM my_view
        WHERE string = ''Strings must use double apostrophe''
    ');

도움이되기를 바랍니다.하지만 코드가 너무 크면 성 가실 수 있으므로 더 좋은 방법을 찾으면 공유하십시오!


-2
"SELECT *
  INTO 
    @TempCustomer 
FROM 
    Customer
WHERE 
    CustomerId = @CustomerId"

이는 새로운 @tempCustomer테이블 변수를 생성하고 고객으로부터 데이터를 삽입 하는 것을 의미 합니다. 이미 위에서 선언 했으므로 다시 선언 할 필요가 없습니다. 함께하는 것이 좋습니다

INSERT INTO @tempCustomer SELECT * FROM Customer

4
작동하지 않습니다. 여전히 테이블 변수를 미리 선언해야합니다.
Johan Boulé
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.