在存储过程中的 while 块内定义的变量范围 - SQl Server
我在存储过程中遇到了一个有趣的场景(至少对我来说)。想请教专家对此的意见和想法。
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
我期望这个块会给出如下输出
<前><代码>值_10_ 价值_ _ 值_8_ 价值_ _ 值_6_ 价值_ _ 值_4_ 价值_ _ 值_2_ 价值_ _
相反,我得到的输出如下:
值_10_
值_10_
值_8_
值_8_
值_6_
值_6_
值_4_
值_4_
值_2_
值_2_
我想如果我在 while 块内声明一个变量,那么对于每次迭代,它都会将该值重置为 NULL 或默认值(来自 c# 背景)。
如果这是设计使然,那么我的问题是 SQLServer 如何处理 while 块内该变量的“DECLARE”语句?由于变量已经在内存中,它会忽略它吗?
有人可以向我解释一下这种行为吗?
I've come across a interesting scenario (at least for me) in a stored procedure. Would like to have experts opinion and thoughts on it.
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
I was expecting this block will give the output as below
Value_10_ Value_ _ Value_8_ Value_ _ Value_6_ Value_ _ Value_4_ Value_ _ Value_2_ Value_ _
Instead I got output as below:
Value_10_
Value_10_
Value_8_
Value_8_
Value_6_
Value_6_
Value_4_
Value_4_
Value_2_
Value_2_
I thought if I declare a variable inside a while block, then for every iteration it will reset the value to NULL or default value (from c# background).
If this is by design then my question is how does SQLServer treat 'DECLARE' statement for that variable inside while block? Does it ignore it as the variable is already in memory?
Can somebody please explain me this behavior?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
变量范围是整个批处理,在本例中是一个存储过程。
它不会重新声明每个循环
所以这完全符合预期
编辑:
最近有一个 博客文章非常相似。作者很快就纠正了:-)
The variable scope is the whole batch in this case a stored procedure.
It isn't re-declared every loop
So this is exactly as expected
Edit:
There is a recent blog article which is quite similar. The author was quickly corrected :-)
来自 Transact-SQL 变量
DECLARE
本身并不是可执行语句。变量声明都是在编译时识别的,并在执行上下文中为它们保留内存。如果您使用 2008+ Declare 和 Set 语法。然而,语句的 Set 部分将出现在每次循环迭代中。
From Transact-SQL Variables
The
DECLARE
is not in itself an executable statement. The variable declarations are all identified at compile time and the memory reserved for them in the execution context.If you use the 2008+ Declare and Set syntax. The Set part of the statement will occur every loop iteration however.
尝试一下这个有趣的
显然声明代码不必执行。仅在使用前声明。
这不起作用
Try this for fun
Apparently the declare code does not have to be executed. Only be declared before it is used.
This don't work
从声明:
T-SQL 中不再有“本地”作用域规则。这也意味着您不能在 IF 和 ELSE 块内声明相同的变量名。
Declare 所做的只是声明一个变量。它与赋值无关。任何从未被赋值的变量的值为
NULL
。但此后,变量值再次变为 NULL 的唯一方法是通过显式赋值。因此,如果您需要在每次循环迭代的顶部将其设置为 NULL,则必须显式分配它。
From Declare:
There are no more "local" scoping rules in T-SQL. It also means that you can't declare the same variable name inside IF and ELSE blocks.
All Declare does is declare a variable. It has no relation to assignment. The value of any variable that has never been assigned to is
NULL
. But thereafter, the only way the variables value will becomeNULL
again is through an explicit assignment.If you need it to be
NULL
at the top of each loop iteration, therefore, you must explicitly assign it.在 T-SQL 中,
WHILE..END
没有单独的作用域,例如,您可以在WHILE
的之后
。SELECT @insidevalue
结束In T-SQL a
WHILE..END
is not individually scoped, you can for exampleSELECT @insidevalue
after theWHILE
'sEND
.整数数据类型通常没有 NULL,只有 0 的
Declare 语句不会每次在循环内发生,
为什么不直接使用
这给出:
Integer data types often don't have NULL's only 0's
Declare statement won't happen each time within the loop
why don't you just use
That gives: