首页 > 解决方案 > 带有 DataReader 的存储过程

问题描述

尝试使用存储过程“sp_receiptload”清理代码时;数据没有通过。

我想使用存储过程来减少代码行。以下是我目前拥有的作品。我想使用 SqlCommand receiptload_cmd = new SqlCommand("sp_receiptload") ,它包含单个批处理查询中的所有查询。我想使用多个阅读器删除。当我尝试实施时;使用 nextresult 没有移动结果。当我在第一行前面放置一段时间时,错误是阅读器未打开。

        using (SqlConnection sqlconn = new SqlConnection(conn))
        {
            using (SqlCommand vendor_cmd = new SqlCommand("SELECT * FROM ICVENDOR ORDER BY name;", sqlconn))
            {
                sqlconn.Open();
                using (SqlDataReader reader = vendor_cmd.ExecuteReader())
                {
                    reader.Read();
                    DataTable dt = new DataTable();
                    dt.Columns.Add("vendor_id", typeof(int));
                    dt.Columns.Add("name", typeof(string));
                    dt.Load(reader);
                    cb_vendor.DataSource = dt.DefaultView;
                    cb_vendor.DisplayMember = "name";
                    cb_vendor.ValueMember = "vendor_id";
                    reader.Close();
                }
                using (SqlCommand hcmd = new SqlCommand("SELECT TOP 1 H_ID FROM ICRECEIPTH ORDER BY h_id DESC", sqlconn))
                {
                    SqlDataReader reader = hcmd.ExecuteReader();
                    if (reader.Read())//this is required to read - if more tan one block of data use while this .read is required to fetch the result
                    {
                        maxh_id = reader.GetInt32(0);
                        newh_id = maxh_id + 1;
                        double digits = Math.Floor(Math.Log10(newh_id) + 1);
                        double num0 = 10 - digits;
                        string snum00 = "";
                        for (int i = 0; i < num0; i++)
                        {
                            string snum0 = (i * 0).ToString();
                            snum00 = snum00 + snum0;
                        }
                        string docnum = "RCP" + snum00 + newh_id.ToString();
                        tb_docnum.Text = docnum;

                    }
                    reader.Close();
                }
                using (SqlCommand cmd1 = new SqlCommand("SELECT item_id FROM ICITEM", sqlconn))
                {
                    using (SqlDataReader reader1 = cmd1.ExecuteReader())
                    {
                        while (reader1.Read())
                        {
                            items.Add(reader1.GetString(0));
                        }
                        reader1.Close();
                    }

                    dataGridView1.Columns["Item"].Visible = false;
                    DataGridViewComboBoxColumn Item_cbcol = new DataGridViewComboBoxColumn();
                    Item_cbcol.HeaderText = "Item";
                    Item_cbcol.Name = "Item_cbcol";
                    Item_cbcol.Items.Add("True");
                    Item_cbcol.DataSource = items.ToList();
                    dataGridView1.Columns.Add(Item_cbcol);
                    dataGridView1.Columns["Item_cbcol"].DisplayIndex = 1;
                    Item_cbcol.AutoComplete = Enabled;
                    Item_cbcol.FlatStyle = FlatStyle.Flat;

                    foreach (DataGridViewRow row in dataGridView1.Rows)
                    {
                        row.Cells["Item_cbcol"].Value = row.Cells["Item"].Value;
                    }

                    tb_docnum.Enabled = false;

                }
                sqlconn.Close();

标签: c#

解决方案


我不会仅仅为简单的 SELECT 查询创建存储过程,这些查询返回一组没有任何特定复杂逻辑的记录。性能可能会更好,但将来的维护会更复杂。

鉴于您对检索的每个表都有不同的处理需求,并且您可能检索的数据量有限,我将使用 DataSet 和 DataAdapter

using(SqlConnection con = new SqlConnection("........."))
{
    con.Open();
    string sqlText = @"SELECT name, vendor_id FROM ICVENDOR ORDER BY name;
                      SELECT TOP 1 H_ID FROM ICRECEIPTH ORDER BY h_id DESC;
                      SELECT item_id FROM ICITEM",
    DataSet ds = new DataSet();
    SqlCommand cmd = new SqlCommand(sqlText, con);
    SqlDataAdapter da = new SqlDataAdapter(cmd);
    da.Fill(ds);
    ProcessTableICVendor(ds.Tables[0]);
    ProcessTableICReceipt(ds.Tables[1]);
    ProcessTableICItem(ds.Tables[2]);
}

请注意,我已将第一个查询更改为仅返回所需的字段。所以你不需要一个中间表来初始化组合框。

当然 ProcessTableICxxx 方法是您已经编写的代码的占位符


推荐阅读