在存储过程中的while块中定义的变量范围 - SQl Server

JPR*_*ddy 26 sql-server variables scope declaration sql-server-2008

我在存储过程中遇到了一个有趣的场景(至少对我而言).想有专家的意见和想法.

DECLARE @loopcounter INT
SET @loopcounter=10

WHILE @loopcounter > 0
BEGIN
  DECLARE @insidevalue int

  IF (@loopcounter%2 = 0)
  SET @insidevalue = @loopcounter

  PRINT 'Value_' + CAST(@insidevalue AS NVARCHAR) + '_'

  SET @loopcounter = @loopcounter - 1
END
Run Code Online (Sandbox Code Playgroud)

我期待这个块将给出如下输出

Value_10_

Value_ _

Value_8_

Value_ _

Value_6_

Value_ _

Value_4_

Value_ _

Value_2_

Value_ _
Run Code Online (Sandbox Code Playgroud)

相反,我输出如下:

Value_10_

Value_10_

Value_8_

Value_8_

Value_6_

Value_6_

Value_4_

Value_4_

Value_2_

Value_2_

我想如果我在while块中声明一个变量,那么对于每次迭代,它会将值重置为NULL或默认值(来自c#background).

如果这是设计的那么我的问题是SQLServer如何在块内处理该变量的'DECLARE'语句?是否因为变量已经在内存中而忽略它?

有人可以解释一下这种行为吗?

gbn*_*gbn 34

变量作用域是整个批处理,在这种情况下是存储过程.

它不会在每个循环中重新声明

所以这完全符合预期

编辑:

最近的博客文章非常相似.作者很快得到纠正:-)

  • 我习惯于手动重置我在T-SQL循环中声明的变量,以防止这种行为.如果你习惯用C#这样的语言工作,那确实很奇怪. (11认同)
  • 如果你想这样说,是的.但它没有被忽视,因为它没有任何意义.SQL没有您期望的范围. (4认同)

Mar*_*ith 16

Transact-SQL变量

变量的范围是可以引用变量的Transact-SQL语句的范围.变量的范围从声明它的位置延迟到声明它的批处理或存储过程的结尾.

DECLARE本身并不是一个可执行语句.变量声明都在编译时标识,并在执行上下文中为它们保留内存.

如果您使用2008+声明和设置语法.然而,语句的Set部分在每次循环迭代中发生.

DECLARE @loopcounter INT
SET @loopcounter=10

WHILE @loopcounter > 0
BEGIN
  DECLARE @insidevalue INT = NULL

  IF (@loopcounter%2 = 0)
  SET @insidevalue = @loopcounter

  PRINT 'Value_' + CAST(@insidevalue AS NVARCHAR) + '_'

  SET @loopcounter = @loopcounter - 1
END
Run Code Online (Sandbox Code Playgroud)


Mik*_*son 12

试试这个很有趣

if 1 = 0
begin
  -- will never happen
  declare @xx int
end  
else  
begin
  set @xx = 1
end  
print @xx
Run Code Online (Sandbox Code Playgroud)

显然,声明代码不必执行.仅在使用之前声明.

这不起作用

if 1 = 0
begin
  -- will never happen
  set @xx = 1
end  
else  
begin
  declare @xx int
end  
print @xx
Run Code Online (Sandbox Code Playgroud)

  • +1很棒的例子.将来会无耻地使用 (3认同)
  • @gbn - 请做:) (2认同)
  • +1有趣的是,如果它没有"执行"它也不会拿起初始化器,例如`declare @xx int = 999` (2认同)

Dam*_*ver 6

来自声明:

局部变量的范围是声明它的批处理.

T-SQL中没有"本地"范围规则.它还意味着您不能在IF和ELSE块中声明相同的变量名称.

所有Declare都声明了一个变量.它与任务无关.从未分配给的任何变量的值是NULL.但此后,变量值NULL再次变为唯一的方式是通过明确的赋值.

因此,如果您需要它NULL位于每个循环迭代的顶部,则必须明确指定它.