SELECT @local_variable (Transact-SQL)

适用于:yesSQL Server(所有支持的版本)YesAzure SQL 数据库YesAzure SQL 托管实例yesAzure Synapse Analytics

将局部变量设置为表达式的值。

要分配变量,建议使用 SET @local_variable,而不是 SELECT @local_variable。

Topic link iconTransact-SQL 语法约定

语法

SELECT { @local_variable { = | += | -= | *= | /= | %= | &= | ^= | |= } expression } 
    [ ,...n ] [ ; ]  

注意

若要查看 SQL Server 2014 及更早版本的 Transact-SQL 语法,请参阅早期版本文档

参数

@local_variable

要为其赋值的声明变量。

{= | += | -= | *= | /= | %= | &= | ^= | |= }
将右边的值赋给左边的变量。

复合赋值运算符:

operator action
= 将后面的表达式赋给变量。
+= 添加并赋值
-= 相减并赋值
*= 乘并赋值
/= 除并赋值
%= 取模并赋值
&= “位与”并赋值
^= “位异或”并赋值
|= “位或”并赋值

expression

为任意有效的表达式。 此参数包含一个标量子查询。

备注

SELECT @local_variable 通常用于将单个值返回到变量中 。 但是,如果 expression 是列的名称,则可返回多个值 。 如果 SELECT 语句返回多个值,则将返回的最后一个值赋给变量。

如果 SELECT 语句没有返回行,变量将保留当前值。 如果 expression 是不返回值的标量子查询,则将变量设为 NULL 。

一个 SELECT 语句可以初始化多个局部变量。

注意

包含变量赋值的 SELECT 语句不能也用于执行通常的结果集检索操作。

示例

A. 使用 SELECT @local_variable 返回单个值

在以下示例中,为变量 @var1 赋值“Generic Name”。 由于 Store 表中不存在为 CustomerID 指定的值,因此对该表的查询不返回任何行。 变量会保留“Generic Name”值。

此示例使用 AdventureWorks2019LT 示例数据库,有关详细信息,请参阅 AdventureWorks 示例数据库。 AdventureWorksLT 数据库用作 Azure SQL 数据库 的 sample 数据库。

-- Uses AdventureWorks2019LT
DECLARE @var1 VARCHAR(30);         
SELECT @var1 = 'Generic Name';         
SELECT @var1 = [Name]
FROM SalesLT.Product         
WHERE ProductID = 1000000; --Value does not exist
SELECT @var1 AS 'ProductName';  

下面是结果集:

Company Name  
------------------------------  
Generic Name  

B. 使用 SELECT @local_variable 返回 null

在以下示例中,使用了一个子查询为 @var1 赋值。 由于为 CustomerID 请求的值不存在,因此子查询不返回值,并将变量设为 NULL

此示例使用 AdventureWorks2019LT 示例数据库,有关详细信息,请参阅 AdventureWorks 示例数据库。 AdventureWorksLT 数据库用作 Azure SQL 数据库 的 sample 数据库。

-- Uses AdventureWorks2019  
DECLARE @var1 VARCHAR(30);   
SELECT @var1 = 'Generic Name';
   
SELECT @var1 = (SELECT [Name]
FROM SalesLT.Product         
WHERE ProductID = 1000000); --Value does not exist   

SELECT @var1 AS 'Company Name';  

下面是结果集。

Company Name  
----------------------------  
NULL  

C. 递归变量赋值的反模式使用

避免将以下模式用于变量和表达式的递归使用:

SELECT @Var = <expression containing @Var> 
FROM 
...

在这种情况下,不能保证 @Var 会逐行更新。 例如,对于所有行,@Var 可以设置为初始值 @Var。 这是因为处理赋值的顺序和频率具有不确定性。 这适用于包含变量字符串串联的表达式(如下所示),但也适用于带有非字符串变量或 + = 样式运算符的表达式。 对于基于集的操作(而不是逐行操作),请改用聚合函数。

对于字符串串联,请改为考虑 SQL Server 2017 (14.x) 中引入的 STRING_AGG 函数,用于需要有序字符串串联的场景。 有关详细信息,请参阅 STRING_AGG (Transact-SQL)。 此示例使用 AdventureWorks2016 或 AdventureWorks2019 示例数据库。 有关详细信息,请参阅 AdventureWorks sample databases(AdventureWorks 示例数据库)。

要避免问题的示例,在此例中,使用 ORDER BY 尝试对串联进行排序会导致列表不完整:

DECLARE @List AS nvarchar(max);
SELECT @List = CONCAT(COALESCE(@List + ', ',''), p.LastName)
  FROM Person.Person AS p
  WHERE p.FirstName = 'William'
  ORDER BY p.BusinessEntityID; 
SELECT @List;

结果集:

(No column name)
---
Walker

不妨考虑:

DECLARE @List AS nvarchar(max);
SELECT @List = STRING_AGG(p.LastName,', ') WITHIN GROUP (ORDER BY p.BusinessEntityID)
  FROM Person.Person AS p
  WHERE p.FirstName = 'William';
SELECT @List;       

结果集:

(No column name)
---
Vong, Conner, Hapke, Monroe, Richter, Sotelo, Vong, Ngoh, White, Harris, Martin, Thompson, Martinez, Robinson, Clark, Rodriguez, Smith, Johnson, Williams, Jones, Brown, Davis, Miller, Moore, Taylor, Anderson, Thomas, Lewis, Lee, Walker

另请参阅

后续步骤