変数 (Transact-SQL)

Applies to: SQL Server Azure SQL Database Azure SQL Managed Instance Azure Synapse Analytics Analytics Platform System (PDW) Microsoft Fabric の SQL 分析エンドポイント Microsoft Fabric のウェアハウス

Transact-SQL ローカル変数は、特定の型の単一データ値を保持できるオブジェクトです。 バッチ内の変数とスクリプトは、通常、次の場合に使用されます。

  • ループが実行された回数をカウントするか、ループが実行される回数を制御するカウンターとして。
  • 流れ制御ステートメントによって検査されるデータ値を保持する場合。
  • ストアド プロシージャのリターン コードや関数の戻り値によって返されるデータ値を保存する場合。

解説

一部の Transact-SQL システム関数の名前には、2 つの "アット" マーク (@@) で始まるものがあります。 以前のバージョンの SQL Server では、 @@ 関数はグローバル変数と呼ばれ、 @@ 関数は変数ではなく、変数と同じ動作を持っていません。 @@関数はシステム関数であり、構文の使用は関数の規則に従います。

ビューで変数を使用することはできません。

変数への変更は、トランザクションのロールバックの影響を受けません。

Transact-SQL 変数を宣言する

DECLARE ステートメントは、次の方法で Transact-SQL 変数を初期化します。

  • 名前を割り当てます。 名前は 1 つの @ で始まる必要があります。

  • システム提供のデータ型またはユーザー定義データ型と長さを割り当てます。 数値変数の場合は、有効桁数と小数点以下桁数も割り当てます。 XML 型の変数の場合、省略可能なスキーマ コレクションが割り当てられる場合があります。

  • 値を NULL に設定します。

たとえば、次の DECLARE ステートメントでは、int データ型を持つ @mycounter という名前のローカル変数を作成します。 既定では、この変数の値は NULL

DECLARE @MyCounter INT;

複数のローカル変数を宣言するには、最初のローカル変数を定義した後にコンマを付け、次のローカル変数名とデータ型を指定します。

たとえば、次の DECLARE ステートメントは、 @LastName@FirstName@StateProvinceという名前の 3 つのローカル変数を作成し、それぞれを初期化して NULLします。

DECLARE @LastName NVARCHAR(30), @FirstName NVARCHAR(20), @StateProvince NCHAR(2);

別の例では、次の DECLARE ステートメントでは、 @IsActive というブール値変数が作成されます。この変数は bit として宣言され 値は 0 (false) です。

DECLARE @IsActive BIT = 0;

変数スコープ

変数のスコープは、その変数を参照できる Transact-SQL ステートメントの範囲になります。 変数のスコープは、宣言された時点から、宣言されたバッチまたはストアド プロシージャの末尾まで続きます。 たとえば、次のスクリプトでは、変数が ( GO キーワードで区切られた) 1 つのバッチで宣言され、別のバッチで参照されるため、構文エラーが発生します。

USE AdventureWorks2022;
GO

DECLARE @MyVariable INT;

SET @MyVariable = 1;
GO

SELECT BusinessEntityID,
    NationalIDNumber,
    JobTitle
FROM HumanResources.Employee
WHERE BusinessEntityID = @MyVariable;

変数はローカル スコープを持ち、定義されているバッチまたはプロシージャ内でのみ表示されます。 次の例では、 sp_executesql の実行用に作成された入れ子になったスコープは、上位のスコープで宣言された変数にアクセスできないため、戻り値とエラーが返されます。

DECLARE @MyVariable INT;
SET @MyVariable = 1;
EXECUTE sp_executesql N'SELECT @MyVariable'; -- this produces an error

Transact-SQL 変数に値を設定する

変数が最初に宣言されると、その値は NULL に設定されます。 変数に値を割り当てるには、 SET ステートメントを使用します。 変数に値を代入する場合は、この方法を使用することをお勧めします。 変数には、 SELECT ステートメントの選択リストで参照されることで、値を割り当てることもできます。

SET ステートメントを使用して変数に値を代入するには、変数名とその変数に代入する値を含めます。 変数に値を代入する場合は、この方法を使用することをお勧めします。 次のバッチの例では、2 つの変数を宣言し、それぞれに値を代入し、WHERE ステートメントの SELECT 句でその値を使用しています。

USE AdventureWorks2022;
GO

-- Declare two variables.
DECLARE @FirstNameVariable NVARCHAR(50),
    @PostalCodeVariable NVARCHAR(15);

-- Set their values.
SET @FirstNameVariable = N'Amy';
SET @PostalCodeVariable = N'BA5 3HX';

-- Use them in the WHERE clause of a SELECT statement.
SELECT LastName,
    FirstName,
    JobTitle,
    City,
    StateProvinceName,
    CountryRegionName
FROM HumanResources.vEmployee
WHERE FirstName = @FirstNameVariable
    OR PostalCode = @PostalCodeVariable;
GO

選択リストの中で変数を参照して、変数に値を代入することもできます。 変数が選択リストで参照されている場合は、スカラー値を割り当てるか、 SELECT ステートメントは 1 行のみを返す必要があります。 次に例を示します。

USE AdventureWorks2022;
GO
DECLARE @EmpIDVariable INT;

SELECT @EmpIDVariable = MAX(EmployeeID)
FROM HumanResources.Employee;
GO

警告

1 つの SELECT ステートメントに複数の代入句がある場合、SQL Server では式の評価順序は保証されません。 効果は、割り当て間に参照がある場合にのみ表示されます。

SELECT ステートメントが複数の行を返し、変数が非スカラー式を参照する場合、変数は結果セットの最後の行の式に対して返される値に設定されます。 たとえば、次のバッチ @EmpIDVariable では、最後に返された行の BusinessEntityID 値 ( 1) に設定されます。

USE AdventureWorks2022;
GO
DECLARE @EmpIDVariable INT;

SELECT @EmpIDVariable = BusinessEntityID
FROM HumanResources.Employee
ORDER BY BusinessEntityID DESC;

SELECT @EmpIDVariable;
GO

次のスクリプトは小さなテスト テーブルを作成し、そのテーブルに 26 行を設定する例です。 このスクリプトでは変数を使用して次の 3 つのことを行います。

  • ループの実行回数を管理して、挿入する行数を制御します。
  • 整数列に挿入する値を供給します。
  • 文字列に挿入する文字を生成する式の一部として機能させます。
-- Create the table.
CREATE TABLE TestTable (cola INT, colb CHAR(3));
GO

SET NOCOUNT ON;
GO

-- Declare the variable to be used.
DECLARE @MyCounter INT;

-- Initialize the variable.
SET @MyCounter = 0;

-- Test the variable to see if the loop is finished.
WHILE (@MyCounter < 26)
BEGIN;
    -- Insert a row into the table.
    INSERT INTO TestTable
    VALUES
        -- Use the variable to provide the integer value
        -- for cola. Also use it to generate a unique letter
        -- for each row. Use the ASCII function to get the
        -- integer value of 'a'. Add @MyCounter. Use CHAR to
        -- convert the sum back to the character @MyCounter
        -- characters after 'a'.
        (
        @MyCounter,
        CHAR((@MyCounter + ASCII('a')))
        );

    -- Increment the variable to count this iteration
    -- of the loop.
    SET @MyCounter = @MyCounter + 1;
END;
GO

SET NOCOUNT OFF;
GO

-- View the data.
SELECT cola, colb FROM TestTable;
GO

DROP TABLE TestTable;
GO