个人技术站点JASONWU

Keep Coding


  • 主页

  • 文章

  • 搜索

SQL Server 变量声明与赋值

新建: 2025-08-06 编辑: 2025-08-09   |   分类: 后端开发   | 字数: 1102 字

声明并赋值语法

在 SQL Server 中,declare 和 set 语句用于声明变量并为其赋值,可以用一行「声明并赋值」语句来完成。

SQL
1-- 在声明时直接赋值,但这种写法只支持返回一行数据
2declare @test_id int = (select test_id from dbo.WXJ_TEST where test_code = @test_code);

⚠️ 注意:若 select 查询结果为多行,此写法会报错!

问题详解

创建测试表和插入重复数据

SQL
 1-- 删除旧表(如果已存在)
 2if object_id('dbo.WXJ_TEST') is not null
 3    drop table dbo.WXJ_TEST;
 4
 5-- 创建表
 6create table dbo.WXJ_TEST (
 7    test_id   int identity primary key,
 8    test_code varchar(50) not null
 9);
10
11-- 插入重复数据
12insert into dbo.WXJ_TEST (test_code) values
13('CODE001'),
14('CODE002'), -- 不同编码
15('CODE001'); -- 再来一条重复

示例一:变量声明与赋值分开

「逐步赋值:查询多行时的变量行为」,即如果查询结果有多行,则只会保留「最后一行」的 ID。

SQL
 1-- 变量声明与赋值分开
 2declare @test_code varchar(50); -- 声明变量
 3set @test_code = 'CODE001'; -- 赋值变量
 4    
 5declare @test_id int; -- 声明变量
 6select @test_id = test_id from dbo.WXJ_TEST where test_code = @test_code; -- 赋值变量
 7
 8-- 返回变量结果
 9-- 结果为 3,因为 CODE001 的 test_id 是 1 和 3,最后一个被赋值给 @test_id
10select @test_id as [声明与赋值分开, 最终 test_id];

示例二:单行子查询赋值

「单步赋值:多行子查询导致的赋值异常」,即子查询只能返回「一行」的 ID,若返回多行则会报错。

SQL
1-- ❌ 此语句会报错 [子查询返回的值不止一个。当子查询跟随在 =、!=、<、<=、>、>= 之后,或子查询用作表达式时,这种情况是不允许的。]
2declare @test_code2 varchar(50) = 'CODE001';
3declare @test_id2 int = (select test_id from dbo.WXJ_TEST where test_code = @test_code2);

示例三:聚合或只取一行

当查询结果可能返回多行时,必须使用聚合函数(如 max、min)或 top (1) 来确保只返回一行数据。

方式 A:取最大 ID

SQL
1declare @test_code3 varchar(50) = 'CODE001';
2declare @test_id3 int = (
3    select max(test_id)
4    from dbo.WXJ_TEST
5    where test_code = @test_code3
6);
7
8-- 结果为 3,因为 CODE001 的最大 ID 是 3
9select @test_id3 as [取最大 ID];

方式 B:只取第一行

SQL
 1declare @test_code4 varchar(50) = 'CODE001';
 2declare @test_id4 int = (
 3    select top (1) test_id
 4    from dbo.WXJ_TEST
 5    where test_code = @test_code4
 6    order by test_id desc
 7);
 8
 9-- 结果为 3,因为 CODE001 的最大 ID 是 3
10select @test_id4 as [TOP 1];

示例四:获取所有 ID 到表变量

SQL
1declare @test_code5 varchar(50) = 'CODE001';
2declare @ids table (test_id int); -- 声明表变量 @ids
3
4-- 插入多行 ID
5insert into @ids
6select test_id from dbo.WXJ_TEST where test_code = @test_code5;
7
8-- 获取所有 ID
9select * from @ids;

SQL Server 机制

变量声明与赋值分开时(select @var = ... from ...)

  • SQL Server 会遍历每一行记录,逐行赋值,每一行都会覆盖变量的值(overwrite)
  • 最终,变量 @test_id 只会保存最后一行的 test_id 值(last value)
  • 不会报错,但可能数据不是我们所期望的

合并一行赋值(declare + = (select ...))

  • 如果返回多行,则会直接报错:
    • 中文环境:子查询返回的值不止一个。当子查询跟随在 =、!=、<、<=、>、>= 之后,或子查询用作表达式时,这种情况是不允许的。
    • 英文环境:Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

总结

  • 「变量声明与赋值分开」不会报错,但只能获取最后一行的值,不可预知
  • 「单行子查询赋值」若返回多行就会直接报错
  • 「保证唯一性」,若无法保证,用聚合(如 max、min)、top (1) 或表变量显式处理多行
#SQL# #SQL Server#

文章:SQL Server 变量声明与赋值

链接:https://www.wuxianjie.net/posts/backend/mssql-declare-assign/

作者:吴仙杰

文章: 本博客文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议,转载请注明出处!

SQL Server 异常处理:自定义错误、事务管理
Python 环境管理一体化:uv VS pip/venv
  • 文章目录
  • 站点概览
吴仙杰

吴仙杰

🔍 Ctrl+K / ⌘K

27 文章
9 分类
25 标签
邮箱 GitHub
  • 声明并赋值语法
  • 问题详解
    • 示例一:变量声明与赋值分开
    • 示例二:单行子查询赋值
    • 示例三:聚合或只取一行
    • 示例四:获取所有 ID 到表变量
    • SQL Server 机制
  • 总结
© 2021-2025 吴仙杰 保留所有权利 All Rights Reserved
浙公网安备 33010302003726号 浙ICP备2021017187号-1
0%