SELECT @local_variable (Transact-SQL)

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例Azure Synapse AnalyticsMicrosoft Fabric 中的 SQL 分析终结点Microsoft Fabric 中的仓库

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

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

Transact-SQL 语法约定

语法

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

注意

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

参数

@local_variable

要为其赋值的声明变量。

.- .
将右边的值赋给左边的变量。

复合赋值运算符:

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

expression

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

备注

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

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

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

注意

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

示例

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

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

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

-- Uses AdventureWorks2022LT
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';

下面是结果集:

ProductName
------------------------------
Generic Name

B. 使用 SELECT @local_variable 返回 null

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

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

-- Uses AdventureWorksLT
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)

本文要求使用 AdventureWorks2022 示例数据库,你可从 Microsoft SQL Server 示例和社区项目主页下载。

要避免问题的示例,在此例中,使用 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

另请参阅

后续步骤