分配变量时SET与SELECT?

时间:2010-10-15 19:17:01

标签: sql sql-server sql-server-2005 tsql sql-server-2008

在T-SQL中分配变量时,SETSELECT语句之间有什么区别?

3 个答案:

答案 0 :(得分:384)

Quote,摘自this article

  
      
  1. SET是变量赋值的ANSI标准,SELECT不是。
  2.   
  3. SET一次只能分配一个变量,SELECT可以一次分配多个。
  4.   
  5. 如果从查询中分配,SET只能分配标量值。如果查询返回多个值/行,则SET将引发错误。 SELECT会将其中一个值分配给变量,并隐藏返回多个值的事实(因此您可能永远不会知道其他地方出现问题的原因 - 请对其进行故障排除)
  6.   
  7. 当从查询中分配时,如果没有返回值,则SET将分配NULL,其中SELECT将根本不进行赋值(因此变量不会从其先前的值更改)
  8.   
  9. 就速度差异而言 - SET和SELECT之间没有直接的区别。然而,SELECT能够在一次拍摄中进行多次任务确实比它具有轻微的速度优势。
  10.   

答案 1 :(得分:144)

我认为SET是ANSI标准,而SELECT则不是。另请注意,当找不到值时,下面示例中SETSELECT的行为不同。

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:要为一个变量分配多个值时。变量可以是表,临时表或表变量等。