LoginSignup
1
0

More than 3 years have passed since last update.

T-SQLでループ内のDECLAREによる宣言時、代入を行わないと初期化されない

Last updated at Posted at 2020-03-03

事象

ループ、またはカーソル内で、毎回変数をnullで初期化したい時、DECLAREによる宣言のみだと初期化されない。

原因

  • ループ、カーソルで宣言済み変数名を宣言してエラーにならず、アドレスが更新されない。
  • 代入処理がなければ値は変更されない。 って仕様があるのだと思う。多分。ドキュメントが見つからなかった。

結論

  • DECLAREで初期化する場合、代入をする。
  • または、ループ内のDECLAREを避け、ループの外でDECLAREしてループ内はSETで初期化する。

調査

初期化できるパターン1

BEGIN
  DECLARE @count INT = 0
  WHILE @count < 2
    BEGIN
      SET @count = @count + 1
      DECLARE @id INT = null -- ここ

      PRINT '代入前: null?'
      PRINT CONVERT(NVARCHAR(10), @id)

      SET @id = 1;

      PRINT '代入後: 1?'
      PRINT CONVERT(NVARCHAR(10), @id)

    END
END
GO

-- 結果
[2020-03-03 11:06:41] [S0001] 代入前: null?
[2020-03-03 11:06:41] [S0001]
[2020-03-03 11:06:41] [S0001] 代入後: 1?
[2020-03-03 11:06:41] [S0001] 1
[2020-03-03 11:06:41] [S0001] 代入前: null?
[2020-03-03 11:06:41] [S0001]
[2020-03-03 11:06:41] [S0001] 代入後: 1?
[2020-03-03 11:06:41] [S0001] 1

初期化できるパターン2

BEGIN
  DECLARE @count INT = 0
  WHILE @count < 2
    BEGIN
      SET @count = @count + 1
      DECLARE @id INT = 2 -- ここ

      PRINT '代入前: 2?'
      PRINT CONVERT(NVARCHAR(10), @id)

      SET @id = 1;

      PRINT '代入後: 1?'
      PRINT CONVERT(NVARCHAR(10), @id)

    END
END
GO

-- 結果
[2020-03-03 11:10:45] [S0001] 代入前: 2?
[2020-03-03 11:10:45] [S0001] 2
[2020-03-03 11:10:45] [S0001] 代入後: 1?
[2020-03-03 11:10:45] [S0001] 1
[2020-03-03 11:10:45] [S0001] 代入前: 2?
[2020-03-03 11:10:45] [S0001] 2
[2020-03-03 11:10:45] [S0001] 代入後: 1?
[2020-03-03 11:10:45] [S0001] 1

初期化できないパターン

BEGIN
  DECLARE @count INT = 0
  WHILE @count < 2
    BEGIN
      SET @count = @count + 1
      DECLARE @id INT -- ここ

      PRINT '代入前: null?'
      PRINT CONVERT(NVARCHAR(10), @id)

      SET @id = 1;

      PRINT '代入後: 1?'
      PRINT CONVERT(NVARCHAR(10), @id)

    END
END
GO

-- 結果
[2020-03-03 11:09:56] [S0001] 代入前: null?
[2020-03-03 11:09:56] [S0001]
[2020-03-03 11:09:56] [S0001] 代入後: 1?
[2020-03-03 11:09:56] [S0001] 1
[2020-03-03 11:09:56] [S0001] 代入前: null?
[2020-03-03 11:09:56] [S0001] 1
[2020-03-03 11:09:56] [S0001] 代入後: 1?
[2020-03-03 11:09:56] [S0001] 1

参考

SQLSercer - DECLARE

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0