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就应该初始化变量值,那么你将永远找不到错误在哪。真是一个大大的陷阱,希望同学们会注意到。



你可能感兴趣的:(SQL,Server)