c# - 对于 ADO,使用 SqlDataAdapter.FillSchema 清除@ReturnValues 和其他标记为输出的存储过程参数

标签 c# sql-server sqldataadapter

[编辑 - 答案的解释位于问题的底部,因为从接受的答案来看,微妙之处并不完全明显。]

原始问题:

在做出进一步努力之前,我正在寻找一个快速的“是的,这种方法应该可行”的答案。

场景:

  • 我有一个运行查询的简单 SQL Server 存储过程。我还想 (1) 返回一个声明为 OUTPUTvarchar(100) 参数,(2) 使用 @ReturnValue 返回一个进一步的(整数)值。
  • 我使用 SqlDatAdapter.DataSet.Fill() 方法从 C# 调用此过程。
  • 回到 C# 代码,我可以访问过程参数,但无法获取 @ReturnValue 或其他 OUTPUT 参数的值。

我在期待什么?

  • SqlDataAdapter 填充过程从选择中获取数据。这可行,我可以在 C# 中访问这些数据。
  • 标记为 OUTPUT 的 SQL Server 存储过程参数的值以及自动 @ReturnValue 参数,可在 C# 中使用。

我看到了什么?

  • 数据按预期从查询中返回。
  • C# 中存在 SQL 命令参数,但其 .Value 属性为空。

我做了什么研究?

  • 大量谷歌搜索包含 SqlDataAdapter@returnvalue 的匹配结果。没有显着的积极结果。
  • 仔细研究了与 SqlDataAdapter 相关的旧 SO 问题 - 似乎没有任何内容与我的问题重叠。
  • 发布了此问题。

我需要询问 SO 社区这是否可能。那么 - 是否可以从与 SqlDatAdapter.DataSet.Fill() 一起使用的存储过程中收集 OUTPUT 参数值?

如果答案是肯定的并且没有简单的示例,那么我会将代码缩减为代表性案例并将其发布到此处(希望)进行社区调试。

编辑 感谢@NDJ 和提供的示例代码,我能够确认 SqlDatAdapter.DataSet.Fill() 不会 干扰存储过程返回值。然后我继续发现我的问题是由立即调用 SqlDatAdapter.DataSet.FillScheam() 引起的。这会将数据表的元数据传递到一个方便的矩阵中,我们可以从 C# 访问该矩阵,这是我的用例的一部分。

但是,FillSchema() 会清除存储过程参数值。在我的代码中,我试图在调用 FillSchema 后收集存储过程输出参数值,这就是我所目睹的原因。我找不到任何关于这一点的文档。

如果您的代码如下所示,那么它就能工作。

    da.Fill(ds);

    var returnVal = returnParam.Value; // value as expected

    da.FillSchema(ds, SchemaType.Source);

如果你的代码看起来像这样,它将无法工作

    da.Fill(ds);

    da.FillSchema(ds, SchemaType.Source);

    var returnVal = returnParam.Value; // value reset by prev line !!!!

最佳答案

是的,你可以。

Create PROCEDURE TestSP
    @test varchar(max) output
AS
BEGIN
    select @test = 'abc'
    select top 10 * from MyTable
    return 4

END




using (SqlConnection connection = new SqlConnection(conString))
        {
            connection.Open();

            SqlCommand cmd = new SqlCommand("TestSP", connection);
            cmd.CommandType = CommandType.StoredProcedure;

            SqlParameter param = new SqlParameter("@test", SqlDbType.VarChar, -1);
            param.Direction = ParameterDirection.Output;

            var returnParam = cmd.Parameters.Add("@Return", SqlDbType.Int);
            returnParam.Direction = ParameterDirection.ReturnValue;

            cmd.Parameters.Add(param);

            SqlDataAdapter da = new SqlDataAdapter(cmd);
            DataSet ds = new DataSet();
            da.Fill(ds);

            var returnVal = returnParam.Value; //4
            var output = param.Value; // abc
            var data = ds.Tables[0].Rows[0][0];  //data from my table
        }

关于c# - 对于 ADO,使用 SqlDataAdapter.FillSchema 清除@ReturnValues 和其他标记为输出的存储过程参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62598240/

相关文章:

c# - iTextSharp文档中PageNumber和PageCount的区别

c# - DataContractJsonSerializer DateTime 隐式时区转换

c# - Take() 是否强制 LINQ 枚举结果 IEnumerable?

sql-server - 在 SQL Server 中为每条记录创建行到列

c# - Entity Framework 6 - 计时查询

c# - 在 C# 中从数据库加载组合框

c# - 通过 C# : Transition into COM context 0x56b098 创建 Excel 时出错

c# - 在 C# 中使用网络摄像头

sql-server - 将电力查询迁移到 SSAS 或 SSIS?

c# - 使用 SqlDataAdapter 更新数据库 View