惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

阮一峰的网络日志
阮一峰的网络日志
The GitHub Blog
The GitHub Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
雷峰网
雷峰网
U
Unit 42
Y
Y Combinator Blog
I
InfoQ
P
Proofpoint News Feed
Engineering at Meta
Engineering at Meta
量子位
Microsoft Security Blog
Microsoft Security Blog
B
Blog
The Cloudflare Blog
F
Fortinet All Blogs
Google DeepMind News
Google DeepMind News
MyScale Blog
MyScale Blog
C
Check Point Blog
S
SegmentFault 最新的问题
爱范儿
爱范儿
博客园 - 叶小钗
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Hugging Face - Blog
Hugging Face - Blog
罗磊的独立博客
T
Tailwind CSS Blog

博客园 - Shapley

项目心得 进程间通讯方式 C#使用MCP协议调用大模型示例 SQL Server LEAD函数实践 sql server行专列一例 数据库字段排序方法两则 Sql Server生成ULID例子 审批流进化记 winform+Task+async 献丑贴:Task.Run中foreach优化 Sql Server Begin TRY sample No service for type 'Microsoft.AspNetCore.Mvc.ViewFeatures.Filters.ValidateAntiforgeryTokenAuthorizationFilter' has been registered. 某低代码平台自定义控件技术点 Element-plus的el-date-picker控件动态切换中英文方案 Chrome浏览器无法查看页面跳转前的请求日志及解决办法 element-plus上传视频并生成缩略图(封面)方案 JWT自动刷新草案 Ajax方法POST的两种提交方式 H5项目在微信浏览器运行实录 修改Dify的Nginx对外访问端口 Task with Console(with SemaphoreSlim) Task实战 asp.net core 9.0发布centos7.9 Barrier CountdownEvent
Sql Server变量声明及使用技巧
Shapley · 2025-04-28 · via 博客园 - Shapley

1.变量声明

变量声明declare @var 其作用域为当前所在的批处理。

1.如果当前语句中有go语句,则在go语句处截止,否则在当前整体代码都有效。

例如:

IF 1=1
BEGIN
   DECLARE @test VARCHAR
   SET @test='1'   
   PRINT 'in if:'+@test
END
PRINT 'out if:'+@test

不报错,如果在最后的print前加入go语句,

IF 1=1
BEGIN
   DECLARE @test VARCHAR
   SET @test='1'   
   PRINT 'in if:'+@test
END
go
PRINT 'out if:'+@test

则输出:

in if:1
消息 137,级别 15,状态 2,第 8 行
必须声明标量变量 "@test"。

若改掉条件:

IF 1=2
BEGIN
   DECLARE @test VARCHAR
   SET @test='1'   
   PRINT 'in if:'+@test
END
PRINT 'out if:'+@test

则也不报错,充分说明,无论if条件是否命中,则其中的declare都会被执行。

若声明时默认赋值呢:

IF 1=2
BEGIN
   DECLARE @test VARCHAR='ffff'
   SET @test='1'   
   PRINT 'in if:'+@test
END
PRINT 'out if:'+@test

也输出为空,说明,声明和赋值是分开的,赋值必须要符合条件才行,而声明则无论在什么地方,都及时生效。

以上参考:SQL中的declare用法

2.循环情况:可以在循环过程中声明并用select语句对变量进行赋值(等同于外部声明+内部set null+select赋值)

 CREATE TABLE #a(id int)
 INSERT INTO #a VALUES(1);

 DECLARE @index INT =1,@maxindex int=2;
 WHILE(@index<=@maxindex)BEGIN
            DECLARE @rootid INT=(SELECT id FROM #a WHERE id=@index);
            PRINT(@rootid)
            SET @index=@index+1;
END;

运行上述代码,只输出一次结果1,正常。如果将declare拿出来进行声明,则要注意select为空的情况,即:select结果为空时变量还会携带上次的赋值结果(这一点要特别当心)

DECLARE @rootid INT;
DECLARE @index INT =1,@maxindex int=2;
WHILE(@index<=@maxindex)BEGIN
            SELECT @index=id FROM #a WHERE id=@index);
            PRINT(@rootid)
            SET @index=@index+1;
        END;

则会输出2次1,最后一次虽然没有赋值成功,但是@index会留存上一次的结果,这一点要特别注意。针对这种情况,用set语句进行纠正即可,如下所示:

DECLARE @rootid INT;
DECLARE @index INT =1,@maxindex int=2;
WHILE(@index<=@maxindex)BEGIN
            set @rootid=(SELECT id FROM #a WHERE id=@index);
            PRINT(@rootid)
            SET @index=@index+1;
        END;

运行代码,则只输出一次1。结果正常了。