C# 发票号生成代码精简及MIN查询返回null问题咨询
C# 发票号生成逻辑优化方案
核心优化点说明
针对问题2:空表返回NULL的规避
聚合函数MIN()/MAX()在无匹配记录时会返回一行NULL结果,而非空结果集,所以原有Rows.Count > 0的判断完全失效。解决方法是在SQL层直接用COALESCE(兼容MySQL、SQL Server等多数数据库)把NULL转换为默认值,无需在代码里做多层判断。
针对问题1:代码简化
可以把两次查询合并为单条SQL,一次数据库交互就拿到目标发票号,大幅减少代码行数和IO开销:
SELECT COALESCE( MIN(invno), (SELECT COALESCE(MAX(invno), 0) + 1 FROM invoicemaster) ) AS new_invno FROM invoicemaster WHERE iscleared = 'Y'
这条SQL的逻辑是:优先取已作废的最小发票号,如果没有符合条件的作废记录,就取最大发票号加1,连空表场景下MAX返回NULL的情况也一起处理了,空表时会直接返回1作为首张发票号。
优化后完整C#代码
string sql = @"SELECT COALESCE( MIN(invno), (SELECT COALESCE(MAX(invno), 0) + 1 FROM invoicemaster) ) AS new_invno FROM invoicemaster WHERE iscleared = 'Y'"; config.singleResult(sql); int intInvNo = Convert.ToInt32(config.dt.Rows[0][0]); lblInvNo.Text = intInvNo.ToString("00000000").PadLeft(12);
多用户环境额外注意事项
现有逻辑存在并发冲突风险:多个用户同时查询时可能拿到同一个发票号,建议做以下处理:
- 给
invno字段加唯一约束,避免重复数据入库 - 查询时加行锁或者用事务包裹生成+写入的完整逻辑,保证操作原子性
内容的提问来源于stack exchange,提问作者Mang
相关产品推荐
相关产品推荐

