执行SQL更新语句触发SqlException(0x80131904):子查询返回多值,如何修复?
修复SQL子查询返回多个值的错误
这个错误的核心原因很明确:你UPDATE语句中SET Reference = (...)里的子查询,返回了多个不同的MainRecordNo值,而SQL Server不允许将多值结果直接赋值给单个字段(Reference只能存一个值)。下面给出几种针对性的修复方案,你可以根据业务需求选择:
方案1:取单个匹配值(最常用)
如果业务逻辑允许从多个匹配结果中取任意一个(比如第一条),可以给子查询加上TOP 1,确保只返回单个值。同时优化EXISTS子查询(不需要DISTINCT,用SELECT 1性能更好):
UPDATE Trade SET Reference = ( SELECT TOP 1 temp.MainRecordNo FROM temp WHERE temp.SubRecordNo = Trade.TradeNo AND temp.LinkType = 'ATPD' AND temp.LinkStatus = 'A' AND ISNULL(Trade.Reference, '') <> Temp.MainRecordNo -- 可选:加ORDER BY指定取哪一个,比如按编号排序 ORDER BY temp.MainRecordNo ASC ) WHERE EXISTS ( SELECT 1 FROM Temp WHERE Temp.SubRecordNo = Trade.TradeNo AND Temp.LinkType = 'ATPD' AND Temp.LinkStatus = 'A' AND ISNULL(Trade.CstpReference, '') <> Temp.MainRecordNo )
方案2:合并多个值为字符串(如果需要保留所有结果)
如果业务需要把所有匹配的MainRecordNo都存到Reference字段里(比如用逗号分隔),可以用SQL Server 2017及以上支持的STRING_AGG函数:
UPDATE Trade SET Reference = ( SELECT STRING_AGG(temp.MainRecordNo, ', ') FROM temp WHERE temp.SubRecordNo = Trade.TradeNo AND temp.LinkType = 'ATPD' AND temp.LinkStatus = 'A' AND ISNULL(Trade.Reference, '') <> Temp.MainRecordNo ) WHERE EXISTS ( SELECT 1 FROM Temp WHERE Temp.SubRecordNo = Trade.TradeNo AND Temp.LinkType = 'ATPD' AND Temp.LinkStatus = 'A' AND ISNULL(Trade.CstpReference, '') <> Temp.MainRecordNo )
额外注意事项
- 检查笔误:原语句中
EXISTS子查询用的是Trade.CstpReference,但SET里用的是Trade.Reference,如果这两个是同一个字段,建议统一,避免逻辑不一致。 - 数据校验:如果业务逻辑要求每个TradeNo只能对应一个MainRecordNo,那说明temp表可能存在重复数据,需要先排查清理(比如删除重复的SubRecordNo+LinkType组合)。
内容的提问来源于stack exchange,提问作者Naveen B
相关产品推荐
相关产品推荐

