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

SQL Server WHILE循环实现的拣货单总价计算函数返回0问题求助

问题根因

排查到4个核心错误:

  • 变量未初始化:声明的@fTotalCost没有设置初始值,SQL Server中未初始化的变量默认值为NULL,NULL + 任意数值结果还是NULL,最终赋值给整型返回值时会被转为0
  • 参数拼写错误:循环内查询的WHERE条件中,你把参数@psPickTicket拼写成了@psPickTcket(少了一个字母e),导致子查询永远匹配不到数据,返回的求和结果固定为0
  • LEFT JOIN逻辑错误:你对tblCase用了LEFT JOIN,但后面又加了C.CaseStatus的过滤条件,实际上会等价于INNER JOIN,如果某行拣货单没有符合状态的关联Case记录,该行的金额会被直接忽略
  • 返回值类型错误:函数返回值定义为TInteger整型,你计算的金额是带小数的浮点数,赋值给整型变量会直接丢失小数部分,就算计算正确也会出现精度损失

优化后代码(去掉无意义的循环,直接用单条聚合查询实现,性能更高)

Alter Function fn_CalculateAllocatedPTPrice
  (@psPickTicket   TPickTicketNo)
  -------------------------------
  Returns Decimal(18,2) -- 用高精度小数类型存金额,避免精度损失
As 
Begin
  Declare @fTotalCost Decimal(18,2) = 0; -- 初始化变量

  SELECT @fTotalCost = ISNULL(SUM(P.RetailUnitPrice * P.UnitsOrdered), 0)
  FROM tblPickTicketDtl P
  -- 把Case状态的过滤提前到JOIN条件里,保留LEFT JOIN的语义
  LEFT JOIN tblCase C 
    ON P.PickTicketNo = C.PickTicketNo
    AND C.CaseStatus IN ('A','G','K','E','L','S')
  WHERE P.PickTicketNo = @psPickTicket;

  Return(@fTotalCost);
End

如果你确实需要保留原来的循环写法,只要修正前面提到的3个错误即可:

  1. 给@fTotalCost设置初始值0
  2. 修正参数拼写错误
  3. 调整LEFT JOIN的过滤条件位置
  4. 把返回值改为适合存金额的小数类型

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 23:27:06