SELECT @local_variable (Transact-SQL)

適用対象:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsMicrosoft Fabric の SQL 分析エンドポイントMicrosoft Fabric のウェアハウス

ローカル変数を式の値に設定します。

変数を割り当てるには、SELECT @local_variable ではなく、SET @local_variable を使用することをお勧めします。

Transact-SQL 構文表記規則

構文

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

Note

SQL Server 2014 (12.x) 以前のバージョンの Transact-SQL 構文を確認するには、以前のバージョンのドキュメントを参照してください。

引数

@local_variable

値を割り当てる宣言された変数です。


右側の値を左側の変数に代入します。

複合代入演算子です。

演算子 アクション
= 後続の式を変数に代入します。
+= 加算して代入
-= 減算して代入
*= 乗算して代入
/= 除算して代入
%= 剰余を代入
$ ビットごとの AND 演算を行って代入
^= ビットごとの XOR 演算を行って代入
|= ビットごとの OR 演算を行って代入

式 (expression)

任意の有効な。 これには、スカラー サブクエリが含まれます。

解説

SELECT @local_variable は通常、変数に 1 つの値を返すときに使用します。 ただし、expression が列名の場合は、複数の値を返すことができます。 SELECT ステートメントが複数の値を返した場合は、最後に返された値が変数に割り当てられます。

SELECT ステートメントが行を返さない場合、変数は現在の値を保ちます。 expression が値を返さないスカラー サブクエリの場合、変数は NULL に設定されます。

1 つの SELECT ステートメントで複数のローカル変数を初期化できます。

Note

変数の割り当てを含む SELECT ステートメントを、同時に通常の結果セットの取得に使用することはできません。

A. SELECT @local_variable を使用して値を 1 つ返す

次の例では、変数 @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

こちらもご覧ください

次の手順