当我在 c# sql 的 listview 中插入多个产品时出错。怎么了?

Posted

技术标签:

【中文标题】当我在 c# sql 的 listview 中插入多个产品时出错。怎么了?【英文标题】:Error when i insert multiple products in listview in c# sql. What is wrong? 【发布时间】:2022-01-03 13:09:06 【问题描述】:

我有一个列表视图,它在数据库中添加一些产品。如果我插入一种产品,它会完美运行。这段代码的问题是 cmd2.Parameters.Clear();如果我在表单列表视图中插入多个产品,它只会将最后一个产品发送到数据库。我该怎么做才能插入所有产品,因为如果我不使用 parameters.clear,它似乎根本不起作用。没有抛出错误,只是没有插入产品。

这是代码:

private void InsertOrder_Click(object sender, EventArgs e)
    
      
        //---------------Inserare client--------------------
        SqlCommand cmd = new SqlCommand("InsertClients", con);
        cmd.CommandType = CommandType.StoredProcedure;

        if (TextBoxClientNou.Enabled)
        
            cmd.Parameters.AddWithValue("@NumeClient", TextBoxClientNou.Text);
        

        else
        
            cmd.Parameters.AddWithValue("@NumeClient", ClientExistent.Text);
        

        var IDClientParameter = cmd.Parameters.Add("@IDClient", SqlDbType.Int);
        IDClientParameter.Direction = ParameterDirection.Output;
        con.Open();
        cmd.ExecuteNonQuery();
        var IDClient = (int)IDClientParameter.Value;
        con.Close();


        //--------------------Inserare Produse------------------

        SqlCommand cmd2 = new SqlCommand("InsertProducts", con);
        cmd2.CommandType = CommandType.StoredProcedure;
        

        foreach (ListViewItem item in ListaProduse.Items)
        
            cmd2.Parameters.Clear(); //Problem here
            cmd2.Parameters.AddWithValue("@Denumire", item.Text);
            cmd2.Parameters.AddWithValue("@Cantitate", item.SubItems[1].Text);
            cmd2.Parameters.AddWithValue("@Dimensiuni", item.SubItems[1].Text);
            cmd2.Parameters.AddWithValue("@Comentarii", item.SubItems[1].Text);
            
        

        var IDProductParameter = cmd2.Parameters.Add("@IDProdus", SqlDbType.Int);
        IDProductParameter.Direction = ParameterDirection.Output;
        con.Open();
        cmd2.ExecuteNonQuery();
        var IDProdus = (int)IDProductParameter.Value;
        con.Close();


        //--------------------Inserare comanda-------------------

        SqlCommand cmd3 = new SqlCommand("InsertOrders", con);
        cmd3.CommandType = CommandType.StoredProcedure;
        cmd3.Parameters.AddWithValue("@IDClient", IDClient);
        cmd3.Parameters.AddWithValue("@IDProdus", IDProdus);
        cmd3.Parameters.AddWithValue("@DataInceput", dateTimePicker1.Text);
        cmd3.Parameters.AddWithValue("@DataSfarsit", dateTimePicker2.Text);
        cmd3.Parameters.AddWithValue("@Facturata", factstatus);
        cmd3.Parameters.AddWithValue("@Livrata", livstatus);

        con.Open();
        cmd3.ExecuteNonQuery();
        con.Close();

【问题讨论】:

不要使用addwithvalue。也很难相信您的所有参数(和相关列)都是 nvarchar(50)。 “大小”或“数量”之类的名称闻起来像数值 【参考方案1】:

您必须在循环内执行查询,因为您要在循环中添加参数(如果两个 ListViewItem 有 8 个参数),这就是您收到此错误的原因。

【讨论】:

【参考方案2】:
foreach (ListViewItem item in ListaProduse.Items)
        
            SqlCommand cmd2 = new SqlCommand("InsertProducts", con);
            cmd2.CommandType = CommandType.StoredProcedure;
            cmd2.Parameters.AddWithValue("@DenProd", item.Text);
            cmd2.Parameters.AddWithValue("@ProdQuant", item.SubItems[1].Text);
            cmd2.Parameters.AddWithValue("@ProdSize", item.SubItems[1].Text);
            cmd2.Parameters.AddWithValue("@ProdComm", item.SubItems[1].Text);
            var IDProductParameter = cmd2.Parameters.Add("@ProdID", SqlDbType.Int);
            IDProductParameter.Direction = ParameterDirection.Output;
            con.Open();
            cmd2.ExecuteNonQuery();
            var IDProdus = (int)IDProductParameter.Value;
            con.Close();
        

【讨论】:

【参考方案3】:

您正在添加参数而不清除原件。您可以使用Parameters.Clear(),也可以更改现有参数的Value。然后你需要在循环中执行命令within

请注意,您必须使用using 块来处理连接。如果这样做,连接将自动关闭

明确指定参数类型和长度

var listIds = new List<int>();

using (var con = new SqlConnection(YourConnString))
using (var cmd2 = new SqlCommand("InsertProducts", con)  CommandType = CommandType.StoredProcedure )
using (var cmd3 = new SqlCommand("InsertOrders", con)  CommandType = CommandType.StoredProcedure )

    cmd2.Parameters.Add("@DenProd", SqlDbType.NVarChar, 50);
    cmd2.Parameters.Add("@ProdQuant", SqlDbType.NVarChar, 50);
    cmd2.Parameters.Add("@ProdSize", SqlDbType.NVarChar, 50);
    cmd2.Parameters.Add("@ProdComm", SqlDbType.NVarChar, 50);
    var IDProductParameter = cmd2.Parameters.Add("@ProdID", SqlDbType.Int);
    IDProductParameter.Direction = ParameterDirection.Output;

    cmd3.Parameters.Add("@IDClient", SqlDbType.Int).Value = IDClient;
    cmd3.Parameters.Add("@IDProdus", SqlDbType.Int);
    cmd3.Parameters.Add("@DataInceput", SqlDbType.DateTime).Value = dateTimePicker1.Text;
    cmd3.Parameters.Add("@DataSfarsit", SqlDbType.DateTime).Value = dateTimePicker2.Text;
    cmd3.Parameters.Add("@Facturata", SqlDbType.NVarChar, 50).Value = factstatus;
    cmd3.Parameters.Add("@Livrata", SqlDbType.NVarChar, 50).Value = livstatus;

    con.Open();

    foreach (ListViewItem item in ListaProduse.Items)
    
        cmd2.Parameters["@DenProd"].Value = item.Text;
        cmd2.Parameters["@ProdQuant"].Value = item.SubItems[1].Text;
        cmd2.Parameters["@ProdSize"].Value = item.SubItems[1].Text;
        cmd2.Parameters["@ProdComm"].Value = item.SubItems[1].Text;
        cmd2.ExecuteNonQuery();
        var IDProdus = (int)IDProductParameter.Value; // do something with this value

        cmd3.Parameters.AddWithValue("@IDProdus", IDProdus);
        cmd3.ExecuteNonQuery();
    

我必须说,理想情况下,您应该使用表值参数或SqlBulkCopy 批量执行此操作,它不会对大量行执行。

【讨论】:

var IDProdus 是从 foreach 外部访问的,如果我把它放在里面,它会说“它在当前上下文中不存在” 您需要考虑如何处理多个IDProdus 结果。也许你应该把它们放在一个列表中。这就是为什么我添加了评论// do something with this value var IDProdus = (int)IDProductParameter.Value 中的 IDProdus;我必须从 foreach 外部访问,但我不知道该怎么做。在这里: cmd3.Parameters.AddWithValue("@IDProdus", IDProdus); 这是在 foreach 循环内: var IDProdus = (int)IDProductParameter.Value;我需要从这里访问它: cmd3.Parameters.AddWithValue("@IDProdus", IDProdus); - 在外部 foreach 循环从数据库中的列表视图行中插入产品。我需要访问这个 var,以便我可以在 Orders 表列中插入产品 ID。 再次:你想用它做什么你没有告诉我,你只是说“我需要访问这”。您将获得多个结果,每次循环运行一个结果。你想对每个结果做什么?把它放在一个列表中,什么?

以上是关于当我在 c# sql 的 listview 中插入多个产品时出错。怎么了?的主要内容,如果未能解决你的问题,请参考以下文章

在 ListView C# 中重置页面

c# 用来自多个 Linq 查询的数据填充 listView

当我在 c# 中显示从查询生成的 SQL 时,最后一部分是啥?我可以删除它吗?

使用 C# 从 Excel 2007 批量上传 SQL 服务器时出错

如何使用Stringbuilder将多个Listview Item插入sqldatabase?

如何使新插入的行位于 ListView 之上(Android Studio)