SELECT @local_variable (Transact-SQL)
適用対象: SQL Server Azure SQL データベース Azure SQL Managed Instance Azure Synapse Analytics Microsoft Fabric の SQL 分析エンドポイント Microsoft Fabric のウェアハウス
ローカル変数を式の値に設定します。
変数を割り当てるには、SELECT @local_variable ではなく、SET @local_variable を使用することをお勧めします。
構文
SELECT { @local_variable { = | += | -= | *= | /= | %= | &= | ^= | |= } expression }
[ ,...n ] [ ; ]
引数
@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)」を参照してください。
この記事の Transact-SQL コード サンプルは AdventureWorks2022
または AdventureWorksDW2022
サンプル データベースを使用します。このサンプル データベースは、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