如何在C#中仅调用一次db2.case_bill_totals并分配结果到多变量
解决方法
因为原存储过程db2.case_bill_totals无法修改,要实现单次调用获取三个时间戳的结果,最直接的方案是在数据库层创建一个包装存储过程,内部复用原存储过程并汇总结果,具体步骤如下:
方案一:创建包装存储过程(推荐,真正实现单次数据库调用)
写一个新的DB2存储过程,内部三次调用原存储过程,将结果存入临时表并标记对应的时间戳,最后返回汇总后的结果集。
示例DB2存储过程代码
CREATE PROCEDURE db2.case_bill_totals_batch( IN ts1 TIMESTAMP, IN ts2 TIMESTAMP, IN ts3 TIMESTAMP ) DYNAMIC RESULT SETS 1 LANGUAGE SQL BEGIN -- 创建会话级临时表,字段需与原存储过程返回结果完全匹配,新增标记字段区分时间戳 DECLARE GLOBAL TEMPORARY TABLE session.bill_totals ( -- 替换为原存储过程返回的实际字段 total_amount DECIMAL(18,2), case_count INT, -- 新增字段:标记当前结果对应的查询时间戳 source_timestamp TIMESTAMP ) WITH REPLACE NOT LOGGED; -- 调用原存储过程并插入第一次结果 CALL db2.case_bill_totals(ts1); INSERT INTO session.bill_totals SELECT *, ts1 FROM TABLE(GET DIAGNOSTICS RESULT SET 1); -- 调用原存储过程并插入第二次结果 CALL db2.case_bill_totals(ts2); INSERT INTO session.bill_totals SELECT *, ts2 FROM TABLE(GET DIAGNOSTICS RESULT SET 1); -- 调用原存储过程并插入第三次结果 CALL db2.case_bill_totals(ts3); INSERT INTO session.bill_totals SELECT *, ts3 FROM TABLE(GET DIAGNOSTICS RESULT SET 1); -- 返回所有汇总结果 SELECT * FROM session.bill_totals; END
C#端调用处理
在C#中只需调用这个新的包装存储过程,传入三个时间戳参数,拿到结果后根据source_timestamp字段将数据分配到对应变量:
// 示例代码,需适配你的数据库访问框架(如Dapper、EF Core等) using var connection = new DbConnection("你的连接字符串"); var results = connection.Query<CaseBillTotal>( "db2.case_bill_totals_batch", new { ts1 = timestamp1, ts2 = timestamp2, ts3 = timestamp3 }, commandType: CommandType.StoredProcedure ).ToList(); // 分配到对应变量 var result1 = results.First(r => r.SourceTimestamp == timestamp1); var result2 = results.First(r => r.SourceTimestamp == timestamp2); var result3 = results.First(r => r.SourceTimestamp == timestamp3);
方案二:C#异步并行调用(减少总耗时,但仍为三次数据库请求)
如果无法修改数据库,可以在C#中用并行异步调用同时发起三个请求,等待所有结果返回后再分配变量,能大幅缩短总等待时间:
// 假设你已有调用原存储过程的异步方法 var task1 = FetchCaseBillTotalsAsync(timestamp1); var task2 = FetchCaseBillTotalsAsync(timestamp2); var task3 = FetchCaseBillTotalsAsync(timestamp3); // 等待所有调用完成 await Task.WhenAll(task1, task2, task3); // 分配结果到变量 var result1 = await task1; var result2 = await task2; var result3 = await task3;
注意事项
- 包装存储过程的临时表字段必须与原存储过程返回的结果集完全一致,否则会出现插入失败
- DB2会话级临时表(
SESSION.前缀)仅在当前数据库会话中有效,会话结束后自动销毁,无数据残留风险 - 如果原存储过程返回多个结果集,需调整包装过程中
GET DIAGNOSTICS RESULT SET的索引,确保获取正确的结果集
内容的提问来源于stack exchange,提问作者Rizwan Maqsood
相关产品推荐
相关产品推荐

