You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何未更新任何行的UPDATE语句部分触发INT溢出错误?

为什么同样是不会更新行的UPDATE语句,一个触发INT溢出另一个却不会?

最近碰到一个SQL Server里特别反直觉的问题,来跟大家拆解下:

首先我创建了临时表并插入了测试数据:

CREATE TABLE #t(col1 int)
INSERT INTO #t VALUES(1)

之后用两种方式尝试模拟INT溢出:

  • 方式1:

    UPDATE #t SET col1 = 999999*999999 WHERE col1 = 2
    

    这条语句不会更新任何行(因为表中只有col1=1的数据),但会触发INT溢出错误。

  • 方式2:

    UPDATE #t SET col1 = 999999*999999 WHERE 1 = 2
    

    同样不会更新任何行,但完全不会触发溢出错误。

核心原因:SQL Server的表达式求值逻辑

这背后的关键在于SQL Server对表达式的求值时机判断:

  • 对于第一个语句的WHERE col1 = 2,SQL Server没办法在编译阶段就确定绝对不会有匹配的行(虽然我们知道当前表没有,但它会考虑未来可能有符合条件的数据),所以会提前计算999999*999999这个赋值表达式,结果超出了INT的范围(INT最大值是2147483647,而999999*999999=999998000001),自然触发溢出。
  • 而第二个语句的WHERE 1 = 2是恒假条件,SQL Server在编译阶段就能直接判断出这个条件永远不会匹配任何行,所以会跳过赋值表达式的计算步骤,也就不会触发溢出。

生产环境的隐患

这种问题在包含数值列和分类列的生产表执行UPDATE时会更棘手:比如你写了一个带分类筛选条件的UPDATE,本来以为筛选条件会过滤掉所有行,但如果SQL Server无法提前识别出这是恒假条件,就可能先计算赋值的复杂表达式,导致溢出错误——哪怕实际根本不会修改任何数据。

内容的提问来源于stack exchange,提问作者a4194304

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:31:35