:SQL Server 数据库中批量加入的 SQL 不会严格按顺序执行?
例子如下:
update scm_deliver_goods_order_list set invoice_order_id='',invoice_order_price_f='0',invoice_notax_order_price_f='0',invoice_order_status='4',invoice_order_inputor='sunjingyi',invoice_order_input_time='',invoice_time='' where id='317168'; update scm_deliver_goods_order_list set invoice_order_id='XSFP260819011',invoice_notax_order_price_f='0.36',invoice_order_price_f='0.4068',invoice_order_status='1',invoice_order_inputor='sunjingyi',invoice_order_input_time='2026-08-21',invoice_time='2026-8-21',invoice_order_source_type=0 where id='317168';

结论先说
在同一个批里,两条 UPDATE 语句,SQL Server 是会按书写顺序依次执行的,但你这个案例有个坑:操作同一行同一条记录,连续两次 update,前面那条会被后面那条直接覆盖,不是乱序,是先后覆盖。
注意区分两个概念:
一个批内多条独立语句(分号分隔):按代码书写顺序执行
单条语句内部的行更新:更新多行时,各行之间没有固定执行顺序(这个才是大家常说 “不按顺序” 的场景)
你的两条 SQL 拆解
-- 第1条
update scm_deliver_goods_order_list
set invoice_order_id='',invoice_order_price_f='0',invoice_notax_order_price_f='0',
invoice_order_status='4',invoice_order_inputor='sunjingyi',invoice_order_input_time='',invoice_time=''
where id='317168';
-- 第2条
update scm_deliver_goods_order_list
set invoice_order_id='XSFP260819011',invoice_notax_order_price_f='0.36',invoice_order_price_f='0.4068',
invoice_order_status='1',invoice_order_inputor='sunjingyi',invoice_order_input_time='2026-08-21',invoice_time='2026-8-21',invoice_order_source_type=0
where id='317168';
执行流程:
先执行第 1 条:id=317168 这一行被改成 invoice_order_status='4',其他字段清空 / 置 0
紧接着马上执行第 2 条:同一行,直接覆盖,status 改成1,回填发票信息
👉 最终结果:第一条的效果完全看不见,被第二条覆盖。
不是 SQL 乱序,是先后两次修改同一行。
什么时候 SQL 会 “看起来不按顺序”?
场景 1:单条 UPDATE 更新多行(最常见误区)
update table set col=xx where id in (1,2,3,4)
这一条语句内部,id=1、2、3、4 这几行,数据库内部更新顺序不保证,优化器选择扫描顺序决定,不是按 in 里面的顺序。
✅ 多条语句(多个 update,分号隔开):语句和语句之间顺序保证
❌ 单条语句,一次性更新多行:行之间无顺序保证
场景 2:跨批次、并行执行、触发器
你这个需求正确写法
既然是同一行,不需要两次 update,合并成一条 update即可:
update scm_deliver_goods_order_list
set invoice_order_id='XSFP260819011',
invoice_order_price_f='0.4068',
invoice_notax_order_price_f='0.36',
invoice_order_status='1',
invoice_order_inputor='sunjingyi',
invoice_order_input_time='2026-08-21',
invoice_time='2026-08-21',
invoice_order_source_type=0
where id='317168';
如果你确实必须先置空、再赋值(中间要做日志 / 触发器捕获中间状态),那要加事务,并且中间加延迟或者拆分两个批次,但一般业务场景完全没必要,直接合并。
补充:事务下的顺序
如果包在事务里:
begin tran
update ... where id=317168; --语句1
update ... where id=317168; --语句2
commit
依然按书写顺序执行,只是所有修改直到 commit 才对其他会话可见。事务只保证原子性,不改变同批语句执行顺序。
一句话总结
✅ 多条独立 UPDATE 语句(分号隔开):语句顺序一定按你写的来
❌ 单条 UPDATE 一次性更新多条记录:行与行之间更新顺序不保证
你这个案例,不是乱序,是先后两次更新同一行,后执行的覆盖前面的修改。
该文章在 2026/9/22 15:37:27 编辑过