[sql] 변수를 지정할 때 SET 대 SELECT?

T-SQL에서 변수를 할당 할 때 SETSELECT명령문 의 차이점은 무엇입니까 ?



답변

이 기사 에서 요약 한 인용문 :

  1. SET는 변수 할당에 대한 ANSI 표준이며 SELECT는 아닙니다.
  2. SET은 한 번에 하나의 변수 만 할당 할 수 있으며 SELECT는 한 번에 여러 개의 할당을 수행 할 수 있습니다.
  3. 쿼리에서 할당하는 경우 SET는 스칼라 값만 할당 할 수 있습니다. 쿼리가 여러 값 / 행을 반환하면 SET에서 오류가 발생합니다. SELECT는 값 중 하나를 변수에 할당하고 여러 값이 반환되었다는 사실을 숨 깁니다 (따라서 다른 곳에서 왜 문제가 발생했는지 알 수 없을 것입니다. 문제를 해결하는 것이 재미 있습니다)
  4. 반환 된 값이없는 경우 쿼리에서 할당 할 경우 SET은 NULL을 할당합니다. 여기서 SELECT는 할당을 전혀 수행하지 않으므로 변수는 이전 값에서 변경되지 않습니다.
  5. 속도 차이는 SET과 SELECT간에 직접적인 차이가 없습니다. 그러나 한 번에 여러 번 할당 할 수있는 SELECT 기능은 SET보다 약간의 속도 이점을 제공합니다.

답변

나는 SETANSI 표준 이라고 생각 하지만 SELECT그렇지 않습니다. 또한 값을 찾을 수없는 경우 아래 예에서 SETvs 의 다른 동작에 유의하십시오 SELECT.

declare @var varchar(20)
set @var = 'Joe'
set @var = (select name from master.sys.tables where name = 'qwerty')
select @var /* @var is now NULL */

set @var = 'Joe'
select @var = name from master.sys.tables where name = 'qwerty'
select @var /* @var is still equal to 'Joe' */


답변

쿼리를 작성할 때이 차이점을 명심해야합니다.

DECLARE @A INT = 2

SELECT  @A = TBL.A
FROM    ( SELECT 1 A ) TBL
WHERE   1 = 2

SELECT  @A
/* @A is 2*/

---------------------------------------------------------------

DECLARE @A INT = 2

SET @A = ( 
            SELECT  TBL.A
            FROM    ( SELECT 1 A) TBL
            WHERE   1 = 2
         )

SELECT  @A
/* @A is null*/


답변

ANSI와 속도 등의 것 외에도 항상 중요한 차이점이 있습니다. ANSI 이상의 속도. 이 중요한 간과 때문에 수정 한 버그의 수는 많습니다. 코드 검토 중에 항상 이것을 찾습니다.

-- Arrange
create table Employee (EmployeeId int);
insert into dbo.Employee values (1);
insert into dbo.Employee values (2);
insert into dbo.Employee values (3);

-- Act
declare @employeeId int;
select @employeeId = e.EmployeeId from dbo.Employee e;

-- Assert
-- This will print 3, the last EmployeeId from the query (an arbitrary value)
-- Almost always, this is not what the developer was intending. 
print @employeeId; 

거의 항상 개발자가 의도 한 것이 아닙니다. 위의 쿼리는 간단하지만 매우 복잡하고 단일 값을 반환할지 여부를 알아내는 쿼리는 사소한 것이 아닙니다. 쿼리는 종종 이것보다 더 복잡하며 우연히 단일 값을 반환했습니다. 개발자 테스트 중에는 괜찮습니다. 그러나 이것은 똑딱 거리는 폭탄과 같으며 쿼리에서 여러 결과를 반환 할 때 문제가 발생합니다. 왜? 변수에 마지막 값을 지정하기 때문입니다.

이제 같은 것을 시도해 보자 SET.

 -- Act
 set @employeeId = (select e.EmployeeId from dbo.Employee e);

오류가 발생합니다.

하위 쿼리가 둘 이상의 값을 반환했습니다. 부속 조회가 =,! =, <, <=,>,> = 뒤에 오거나 부속 조회가 표현식으로 사용될 때는 허용되지 않습니다.

왜 “마지막으로 마지막 아이템”을에 할당하고 싶기 때문에 놀랍고 매우 중요합니다 @employeeId. select당신 과 함께 어떤 오류가 발생하지 않으며 당신은 몇 분, 디버깅 시간을 보낼 것입니다.

아마도 하나의 ID를 찾고 SET쿼리를 수정해야 할 것입니다. 따라서 다음과 같은 작업을 수행 할 수 있습니다.

-- Act
-- Notice the where clause
set @employeeId = (select e.EmployeeId from dbo.Employee e where e.EmployeeId = 1);
print @employeeId;

대청소

drop table Employee;

결론적으로 다음을 사용하십시오.

  • SET: 변수에 단일 값을 지정하고 변수가 단일 값에 대한 경우.
  • SELECT: 변수에 여러 값을 지정하려는 경우. 변수는 테이블, 임시 테이블 또는 테이블 변수 등일 수 있습니다.

답변