在T-SQL中分配变量时,SET
和SELECT
语句之间有什么区别?
答案 0 :(得分:384)
- SET是变量赋值的ANSI标准,SELECT不是。
- SET一次只能分配一个变量,SELECT可以一次分配多个。
- 如果从查询中分配,SET只能分配标量值。如果查询返回多个值/行,则SET将引发错误。 SELECT会将其中一个值分配给变量,并隐藏返回多个值的事实(因此您可能永远不会知道其他地方出现问题的原因 - 请对其进行故障排除)
- 当从查询中分配时,如果没有返回值,则SET将分配NULL,其中SELECT将根本不进行赋值(因此变量不会从其先前的值更改)
- 就速度差异而言 - SET和SELECT之间没有直接的区别。然而,SELECT能够在一次拍摄中进行多次任务确实比它具有轻微的速度优势。
醇>
答案 1 :(得分:144)
我认为SET
是ANSI标准,而SELECT
则不是。另请注意,当找不到值时,下面示例中SET
与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' */
答案 2 :(得分:2)
除了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
:要为一个变量分配多个值时。变量可以是表,临时表或表变量等。