用普通T-SQL语句代替游标操作
经常写SQL的同学们都知道, 在Sql Server的IDE中如果SQL嵌套的层次太多, 查看和修改代码将变得非常痛苦, 再加上游标用得不恰当很容易出现"锁"和"性能"问题.
所以通常大大们都劝大家尽量少用游标, 阿飞个人很喜欢将业务逻辑写在存储过程里, 于是也经常遇到需要游标逻辑的地方, 这里就跟大家分享一点使用普通T-SQL语句代替游标的处理方案.
业务需求:
订单表 t_orders (id int, total money, paid money, date datetime)
付款单 t_pays (id int, amount money, date datetime)
付款单和订单关系表 t_relation (pay_id int, order_id int, amount money)
财务付款时, 往 t_pays 插入一条记录, 并且需要按照订单表的时间顺序在 t_relation 表标记出此次付款用于支付了哪些订单, 一个付款单可能会对应多个订单, 一个订单也可能分几次支付, 所以 t_relation 表中存储的是多对多的关系.
存储过程的输入参数 @amount money, 表示此次支付金额
1. 首先插入 t_pays 记录, set @pay_id = SCOPE_IDENTITY(); 获取此次付款单编号
2. 使用一个变量表来存储需要支付的订单
--amount 表示此订单需要支付的金额, pay 表示此次将要支付的金额, sort 用来表示支付顺序 declare @orders table(id int, amount money, pay money, sort int); --使用CTE(Common Table Expressions)列出所有需要支付的订单 with REF(id, amount, sort) as ( select id, total - paid, Row_Number()over(order by date) from t_orders where total > paid ) --然后筛选出此次可以支付的订单, 插入到变量表
--需要注意的是, 普通订单此次支付的金额是 total - paid, 但是最后一个订单, 付款单金额如果不足(@amount < balance)就应该是 @amount - (balance - amount) insert into @orders(id, amount, sort, pay) select K.id, K.amount, K.sort, case when @amount >= T.balance then K.amount else @amount - (T.balance - K.amount) end from REF as K outer apply ( select IsNull(sum(amount), 0) as balance from REF where sort <= K.sort )T where @amount > T.balance - K.amount --这里, T表累加了到K表当前记录为止的应付总额, --可支付的订单应满足的条件是: 付款单金额@amount > 我前面一个订单为止的总额( 即 balance - amount)
3. 开始向关系表插入记录
insert into t_relation(pay_id, order_id, amount) select @pay_id, id, pay from @orders;
4. 更新t_orders 表的 已付金额(paid)
update T set T.paid = T.paid + K.pay from @orders K inner join t_orders T on T.id = K.id
大功告成, 看起来好像有很多语句, 仔细数一下, 其实完成"关系链接"的只有三条语句.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述