CASE语句更新Binary(16)列时出现截断异常的技术求助
问题原因分析
这个异常的核心是SQL Server的隐式数据类型转换导致的,具体来说是你的CASE表达式里分支返回值的类型不统一,触发了不符合预期的类型转换:
- 当你写
CASE Id WHEN 1 THEN 0x4cb47abddf8a9c348c7a7c20abd0b1d5 ELSE 0时,THEN分支返回的是binary(16)类型的字节值,但ELSE分支的0是默认的int(整数)类型。 - SQL Server会根据数据类型优先级统一
CASE表达式的返回类型:int的优先级高于binary,所以整个CASE的结果会被强制转换为int类型。 int类型仅能存储4字节的数据,因此你的16字节binary值会被截断,只保留最后4字节(对应原Hash值的0xabd0b1d5部分)。- 当这个截断后的
int值被赋值回binary(16)列时,SQL Server会自动在前面补0填充到16字节,最终就得到了你看到的0x00000000000000000000000abd0b1d5。
而直接执行UPDATE Table1 SET Hash = 0x4cb47abddf8a9c348c7a7c20abd0b1d5时,没有类型不统一的问题,值直接以binary(16)类型赋值,所以结果正常。
解决办法
只需要保证CASE表达式的所有分支返回相同的数据类型即可,把ELSE分支的0改为binary(16)类型的全0值:
方案1:直接写16字节的全0二进制值
UPDATE Table1 SET Hash = CASE Id WHEN 1 THEN 0x4cb47abddf8a9c348c7a7c20abd0b1d5 ELSE 0x00000000000000000000000000000000 END
方案2:显式转换0为binary(16)类型
UPDATE Table1 SET Hash = CASE Id WHEN 1 THEN 0x4cb47abddf8a9c348c7a7c20abd0b1d5 ELSE CAST(0 AS binary(16)) END
这样CASE表达式的返回类型就统一为binary(16),不会再发生截断的隐式转换,更新结果就符合预期了。
内容的提问来源于stack exchange,提问作者Hopeless
相关产品推荐
相关产品推荐

