You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用ADO.NET在C#中调用表值函数,如何获取返回的结果表?

如何修改.NET代码获取SQL表值函数的返回结果

问题分析

你当前代码存在两个核心问题:

  1. CommandType设置错误:表值函数不能通过CommandType.StoredProcedure调用,必须通过SELECT语句执行,因此要设置为CommandType.Text。
  2. 错误使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 16:47:57