您的位置:首页 > 数据库

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

2015-10-31 10:04 363 查看
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就应该初始化变量值,那么你将永远找不到错误在哪。真是一个大大的陷阱,希望同学们会注意到。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息