답변:
- SET는 변수 할당에 대한 ANSI 표준이며 SELECT는 아닙니다.
- SET은 한 번에 하나의 변수 만 할당 할 수 있으며 SELECT는 한 번에 여러 개의 할당을 수행 할 수 있습니다.
- 쿼리에서 할당하는 경우 SET는 스칼라 값만 할당 할 수 있습니다. 쿼리가 여러 값 / 행을 반환하면 SET에서 오류가 발생합니다. SELECT는 값 중 하나를 변수에 할당하고 여러 값이 반환되었다는 사실을 숨 깁니다 (따라서 다른 곳에서 왜 문제가 발생했는지 알 수 없을 것입니다. 문제를 해결하는 것이 재미 있습니다)
- 반환 된 값이없는 경우 쿼리에서 할당 할 경우 SET은 NULL을 할당합니다. 여기서 SELECT는 할당을 전혀 수행하지 않으므로 변수는 이전 값에서 변경되지 않습니다.
- 속도 차이는 SET과 SELECT간에 직접적인 차이가 없습니다. 그러나 한 번에 여러 번 할당 할 수있는 SELECT 기능은 SET보다 약간의 속도 이점을 제공합니다.
SELECT @Int = @Int + 1, @Int = @Int + 1
하면 @Int
2로 끝납니다. 이는 연속적인 문자열 조작을 수행 할 때 매우 유용 할 수 있습니다.
나는 SET
ANSI 표준 이라고 생각 하지만 SELECT
그렇지 않습니다. 또한 값을 찾을 수없는 경우 아래 예에서 SET
vs 의 다른 동작에 유의하십시오 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' */
select @var = (select name from master.sys.tables where name = 'qwerty')
하면 @var이 null로 표시됩니다. 당신이주는 예제는 같은 쿼리가 아닙니다.
(select name from master.sys.tables where name = 'qwerty')
하나를 name from master.sys.tables where name = 'qwerty'
위해, 다른 하나를 위해 ... 당신은 그것을 보지 않습니까?
(select name from master.sys.tables where name = 'qwerty')
스칼라 하위 쿼리이며 name from master.sys.tables where name = 'qwerty'
간단한 쿼리입니다. 두 가지 다른 표현 은 동일한 결과를 나타내지 않아야하지만, 그들이해야한다는 것을 암시하는 것처럼 보입니다. SET
및 SELECT
키워드에 다른 구현이 있다고 말하려는 경우 예제에서 두 개의 다른 표현식 을 사용해서는 안됩니다 . msdn.microsoft.com/ko-kr/library/ms187330.aspx
쿼리를 작성할 때이 차이점을 명심해야합니다.
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
: 변수에 여러 값을 지정하려는 경우. 변수는 테이블, 임시 테이블 또는 테이블 변수 등일 수 있습니다.