【问题标题】:Return multiple recordsets from stored proc in C#从 C# 中的存储过程返回多个记录集
【发布时间】:2013-09-01 21:13:23
【问题描述】:

我必须将 ASP 经典系统转换为 C#

我有一个存储过程,最多可以返回 7 个记录集(取决于传入的参数)。

我需要知道如何简单地将所有记录集作为单独的 DataTables 返回,这样我就可以遍历所有的数据表,当我到达它的末尾时跳到下一个 DataTable,而不必运行多个 SQL 语句并使用多个适配器。填充语句将每个表添加到数据集中。

在经典中,当我到达循环末尾以移至下一条语句时,这是一个简单的 Do While not objRS.EOF 循环,带有 objRS.NextRecordset()。

有什么我可以使用而不需要完全重写当前后端代码的东西吗?

每个记录集都有不同数量的列和行。它们彼此无关。我们从存储过程中返回多个记录集以减少流量。

例子会很好。

谢谢

【问题讨论】:

    标签: c# asp.net sql datatable dataset


    【解决方案1】:

    这将返回你所需要的一切

    using (SqlConnection conn = new System.Data.SqlClient.SqlConnection(connString))
    {
        using (SqlCommand cmd = new SqlCommand())
        {
            cmd.CommandText = "yoursp";
            cmd.Connection = conn;
            cmd.CommandType = CommandType.StoredProcedure;
    
            conn.Open();
    
            SqlDataAdapter adapter = new SqlDataAdapter(cmd);
    
            DataSet ds = new DataSet();
            adapter.Fill(ds);
    
            conn.Close();
        }
    }
    

    【讨论】:

    • 这是我用来从存储过程中获取多个记录集的方法。为了澄清起见,记录集存储在ds.Tables 中,您可能希望将DataSet ds = new DataSet(); 放在开头,以便可以在using (SqlConnection conn = new System.Data.SqlClient.SqlConnection(connString)) 块之外引用它。只是一个想法。
    • 是的,您可以将其移出。只是举一个例子来说明如何做到这一点;。
    【解决方案2】:

    如果您使用SqlDataAdapter.Fill() 方法填充数据集,那么从存储过程返回的每个记录集都将作为数据集中的数据表返回

    DataSet dataset = new DataSet();
    using (var adapter = new SqlDataAdapter("yourStoredProcedure", yourConnectionString))
    {
        adapter.SelectCommand.CommandType = CommandType.StoredProcedure;
        adapter.Fill(dataset);
    }
    for (int i = 0; i < dataset.Tables.Count; i++)
    {
        // Do something for each recordset
    }
    

    如果您使用 SqlDataReader 则可以使用 SqlDataReader.NextResult() 方法前进到下一个记录集:

    using (var connection = new SqlConnection(yourConnectionString))
    using (var command = new SqlCommand("yourStoredProcedure"))
    {
        connection.Open();
        using (var reader = command.ExecuteReader())
        {
            while (reader.Read())
            {
                // do something with first result set;
            }
            if (reader.NextResult())
            {
                while (reader.Read())
                {
                    // do something with second result set;
                }
            }
            else
            {
                return;
            }
            if (reader.NextResult())
            {
                while (reader.Read())
                {
                    // do something with third result set;
                }
            }
            else
            {
                return;
            }
        }
    }
    

    【讨论】:

    • 我从来不知道你可以使用SqlDataReader.ExecuteReader().NextResult() 获得多个结果集。感谢您的详细回答!
    • 确实可以,我通常更喜欢使用 SqlDataReader,因为它只存储当前记录,而不用担心已经读取的内容和尚未读取的内容,从而降低了内存使用率。然而,this answer 将数据集与数据读取器进行比较有一个很好的类比。
    • 感谢分享 SO 链接!我过去使用过SqlDataReaders,我认为需要维护很多代码。然后我尝试了DataTables 并认为它们要快得多。将来编写其他代码时,我将不得不牢记替代方案!再次感谢分享!
    • 这就是我们所说的完美解决方案
    【解决方案3】:

    您可以使用 if (dr.NextResult())

    来检查 dr 是否有更多记录集 ot no

    然后用 dr.read 再次循环

    试试这个

    string connStr = ConfigurationManager.ConnectionStrings["ConString"].ConnectionString;
    SqlConnection Con = new SqlConnection(connStr);
    
    try
    {
        string str1 = "select productid,productname from products;select VendorFName from vendor";
        SqlCommand com = new SqlCommand(str1, Con);
    
        com.Connection.Open();
    
        SqlDataReader dr = com.ExecuteReader();
    
        DropDownList1.Items.Add("Select Product Id");
        DropDownList2.Items.Add("Select Vendor Name");
    
        while(dr.Read())
        {
            DropDownList1.Items.Add(dr.GetValue(0).ToString());
        }
    
        if (dr.NextResult())
        {
            while (dr.Read())
            {
                DropDownList2.Items.Add(dr.GetValue(0).ToString());
            }
        }
    }
    catch (Exception ex)
    {
    }
    finally
    {
        if (Con.State == ConnectionState.Open)
        {
            Con.Close();
        }
    }
    

    【讨论】:

      【解决方案4】:
      SqlConnection con=new SqlConnection("YourConnection String");
      SqlCommand cmd=new SqlCommand();
      SqlDataAdapter da=new SqlDataAdapter();
      DataSet ds = new DataSet();
      cmd = new SqlCommand("name of your Stored Procedure", con);
      cmd.CommandType = CommandType.StoredProcedure;
      //cmd.Parameters.AddWithValue("@SuperID", id);//if you have parameters.
      da = new SqlDataAdapter(cmd);
      da.Fill(ds);
      con.Close();
      

      在此之后,您可以利用不同的 (7) 记录集使用

      ds.Tables[0]
      ds.Tables[1]
      ds.Tables[2]
      ds.Tables[3]
      ds.Tables[4]
      ds.Tables[5]
      ds.Tables[6]
      

      【讨论】:

      • 谢谢,我喜欢这个答案纯粹是因为我已经有一个带有包装函数的数据类,可以处理连接并在类被销毁时处理它们等。我只是想使用我拥有的现有函数并引用数据集中的表格。
      猜你喜欢
      • 1970-01-01
      • 2014-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-21
      • 1970-01-01
      • 2010-11-28
      • 2017-05-06
      相关资源
      最近更新 更多