SQL Server: T-SQL变量声明陷阱

T-SQL循环操作中声明局部变量,如果没有初始值NULL,下次迭代时会保有上次的值。 这会产生不可预料的大BUG. 看代码:

DECLARE @i int =2
WHILE @i>0
BEGIN
        DECLARE @var varchar(20);
        PRINT @var
        SET @var = CASE WHEN @i=2 THEN 'Test1' ELSE 'Test2' END
        SET @i-=1;
END

我们期待@var 永远为NULL,因为它在循环中第一次声明并且"应该"默认带有NULL值。

实际上结果如下:

NULL

TEST1


这个看起来像是个SQL SERVER BUG,但微软实际上有解释:

即使在循环中DECLARE了多次,但DECLARE 语句只会被编译一次。相当于你只声明了此变量一次,此后循环中继续使用该变量。


个人感觉它不太人性化也不太符合逻辑,微软是不是应该重置这种局部变量的值呢?


正确使用如下:

DECLARE @i int =2
WHILE @i>0
BEGIN
        DECLARE @var varchar(20) = NULL;
        PRINT @var
        SET @var = CASE WHEN @i=2 THEN 'Test1' ELSE 'Test2' END
        SET @i-=1;
END

这还不是最好的写法,T-SQL中变量声明最好都在语句的最开始处:

DECLARE @i int =2
DECLARE @var varchar(20);
WHILE @i>0
BEGIN
        SET @var=NULL
        PRINT @var
        SET @var = CASE WHEN @i=2 THEN 'Test1' ELSE 'Test2' END
        SET @i-=1;
END


在一个复杂的T-SQL或存储过程中,循环语句中没有初始值的局部变量会导致严重的不可预期的错误。如果你意识中DELCARE就应该初始化变量值,那么你将永远找不到错误在哪。真是一个大大的陷阱,希望同学们会注意到。



  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值