如何编写计算库存总价的Microsoft SQL存储过程?(含关联表结构)
计算库存总价的SQL Server存储过程实现
嘿,作为SQL新手就想着用存储过程来标准化这个计算需求,这点很棒!咱们结合你给出的两张表,一步步来实现这个存储过程。
首先先补全你没写完的Item表结构(应该是漏了unit_price的完整定义),推荐用DECIMAL类型来存储单价,避免浮点精度问题:
CREATE TABLE Item( item_id VARCHAR(5) NOT NULL UNIQUE, item_name VARCHAR(20) NOT NULL UNIQUE, item_desc VARCHAR(50) NOT NULL, unit_price DECIMAL(10,2) NOT NULL CHECK(unit_price >= 0) -- 用DECIMAL更适合金额计算 );
接下来分两种场景写存储过程,你可以根据需求选择:
场景1:计算所有角色持有物品的总库存价值
这个存储过程会直接返回所有角色手里物品的总价值:
CREATE PROCEDURE CalculateTotalInventoryValue AS BEGIN -- 关闭"影响行数"的提示消息,让输出更简洁 SET NOCOUNT ON; -- 通过关联两张表,计算数量×单价的总和 SELECT SUM(ci.item_qty * i.unit_price) AS TotalInventoryValue FROM Char_item ci INNER JOIN Item i ON ci.item_id = i.item_id; END;
调用方式:
EXEC CalculateTotalInventoryValue;
场景2:支持指定单个角色,或计算所有角色的总价值
这个版本加了可选参数,灵活性更高——不传参数就计算所有角色的总价值,传角色ID就只算该角色的:
CREATE PROCEDURE CalculateTotalInventoryValue @TargetCharID VARCHAR(5) = NULL -- 可选参数,默认值为NULL AS BEGIN SET NOCOUNT ON; SELECT -- 如果传了角色ID就显示ID,否则显示"所有角色" COALESCE(@TargetCharID, '所有角色') AS CharacterID, SUM(ci.item_qty * i.unit_price) AS TotalInventoryValue FROM Char_item ci INNER JOIN Item i ON ci.item_id = i.item_id -- 参数不为空时筛选指定角色,为空时不做筛选 WHERE ci.char_id = ISNULL(@TargetCharID, ci.char_id) -- 根据参数是否为空来分组 GROUP BY CASE WHEN @TargetCharID IS NOT NULL THEN ci.char_id ELSE '所有角色' END; END;
调用方式:
- 计算所有角色:
EXEC CalculateTotalInventoryValue; - 计算指定角色(比如角色ID为
C001):EXEC CalculateTotalInventoryValue @TargetCharID = 'C001';
一些注意事项
- 为什么用
DECIMAL而不是FLOAT?因为FLOAT是近似数值类型,计算金额时可能出现精度误差,DECIMAL(10,2)可以确保保留两位小数,符合金额计算的需求。 - 执行存储过程需要对应的权限:创建存储过程需要
CREATE PROCEDURE权限,执行需要EXECUTE权限。 - 如果
Char_item里有item_qty=0的记录,SUM会自动忽略吗?不会,但你的表已经有CHECK(item_qty >=0)约束,0的话乘以单价还是0,不影响总结果,如果想排除0数量的记录,可以在WHERE里加ci.item_qty > 0。
内容的提问来源于stack exchange,提问作者Kreetchy
相关产品推荐
相关产品推荐

