使用ADO.NET在C#中调用表值函数,如何获取返回的结果表?
如何修改.NET代码获取SQL表值函数的返回结果
问题分析
你当前代码存在两个核心问题:
- CommandType设置错误:表值函数不能通过
CommandType.StoredProcedure调用,必须通过SELECT语句执行,因此要设置为CommandType.Text。 - 错误使用ExecuteNonQueryAsync:这个方法仅用于执行无返回结果的SQL(如INSERT/UPDATE/DELETE),无法获取查询类语句的返回数据,需要改用数据读取类的异步方法。
修改步骤及完整代码
以下是修正后的.NET代码,同时修正了参数名的错误(函数参数是@TVP,而非@typtblMember,typtblMember是TVP的类型名称):
using (var conn = new SqlConnection(_EDWConnString)) { await conn.OpenAsync(); // 异步打开连接 var tvpData = Member.AsDataTable(); var sql = "SELECT * FROM [EMR].[fnGetMemberOrderDailySummary](@TVP)"; var cmd = new SqlCommand(sql, conn) { CommandType = CommandType.Text }; // 添加TVP参数,参数名对应函数定义的@TVP var dtparam = cmd.Parameters.Add("@TVP", SqlDbType.Structured); dtparam.Value = tvpData; dtparam.TypeName = "typtblMember"; // 指定TVP的类型名称 _logger.Log(LogSeverity.Debug, "开始获取会员订单每日汇总数据"); // 使用SqlDataReader异步读取结果并填充DataTable var resultTable = new DataTable(); using (var reader = await cmd.ExecuteReaderAsync()) { resultTable.Load(reader); } _logger.Log(LogSeverity.Debug, $"获取数据完成,共[{resultTable.Rows.Count}]条记录"); return resultTable; }
关键修改说明
- 修正CommandType和SQL语句:通过
SELECT * FROM 函数名(参数)的方式调用表值函数,CommandType设为Text。 - 正确配置TVP参数:明确指定参数的
TypeName为TVP的类型typtblMember,参数名与函数定义的@TVP一致。 - 改用ExecuteReaderAsync读取数据:通过
SqlDataReader异步读取结果,再加载到DataTable中,拿到函数返回的完整数据集。 - 异步操作添加await:所有异步方法(
OpenAsync、ExecuteReaderAsync)都添加await,确保操作完成后再执行后续逻辑。
如果你更倾向于使用SqlDataAdapter,也可以用以下方式填充DataTable:
using (var adapter = new SqlDataAdapter(cmd)) { await Task.Run(() => adapter.Fill(resultTable)); }
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

