【问题标题】:C# bulk insert to database [duplicate]C#批量插入数据库[重复]
【发布时间】:2021-10-27 14:31:38
【问题描述】:

我有从comboBox 获取id 和从listBox 获取多个值的winform,然后我需要使用我的comboBox 项目的ID 存储这个listBox 项目。

**当前行为`

如果我的listBox 中只有一件商品,它会存储。但是如果有多个项目(这是使用listBox 的目的),它会返回以下错误:

Message: Procedure or function InsertSerial has too many arguments specified.

预期行为

获取listBox中的所有项目并将它们一起添加到数据库中(批量插入)

代码

Table schema

CREATE TABLE [dbo].[Serials] (
    [Id]        INT          IDENTITY (1, 1) NOT NULL,
    [ProductId] INT          NOT NULL,
    [Serial]    VARCHAR (50) NOT NULL,
    [Sold]      BIT          DEFAULT ((0)) NOT NULL,
    PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [FK_Serials_Products] FOREIGN KEY ([ProductId]) REFERENCES [dbo].[Products] ([Id])
);

StoredProcedur

CREATE PROCEDURE [dbo].[InsertSerial]
    @ProductId INT,
    @Serial NVARCHAR(50),
    @Sold INT
AS
    begin
    INSERT into Serials(ProductId, Serial, Sold) values (@ProductId,@Serial,@Sold);
    end

form

// save button
private void snStoreBtn_Click(object sender, EventArgs e)
{
    try
    {
        using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyApp.Properties.Settings.MyAppDatabaseString"].ConnectionString))
        {
            if (cn.State == ConnectionState.Closed)
                cn.Open();
            using (SqlCommand cmd = new SqlCommand("dbo.InsertSerial", cn))
            {
                foreach (var item in listBox1.Items)
                {
                    Console.WriteLine("Item::: {0}", item.ToString());
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@ProductId", selectedProductId);
                    cmd.Parameters.AddWithValue("@Serial", item.ToString()); //Message: Procedure or function InsertSerial has too many arguments specified.
                    cmd.Parameters.AddWithValue("@Sold", "0");
                    cmd.ExecuteNonQuery();
                }
                cn.Close();
            }
            backgroundWorker1.RunWorkerAsync();
            progressBarStoringData.Visible = true;
            progressLabel.Visible = true;
        }
        // clear the listBox
        listBox1.Items.Clear();
    }
    catch (SqlException ex)
    {
        StringBuilder errorMessages = new StringBuilder();
        for (int i = 0; i < ex.Errors.Count; i++)
        {
            errorMessages.Append("Index #" + i + "\n" +
                "Message: " + ex.Errors[i].Message + "\n" +
                "LineNumber: " + ex.Errors[i].LineNumber + "\n" +
                "Source: " + ex.Errors[i].Source + "\n" +
                "Procedure: " + ex.Errors[i].Procedure + "\n");
        }
        Console.WriteLine(errorMessages.ToString());
    }
}

问题

我应该如何循环我的 listBox 项目以正确存储在数据库中?

【问题讨论】:

标签: c# winforms


【解决方案1】:

只添加一次参数,每次执行只需更改它们的值。

            using (SqlCommand cmd = new SqlCommand("dbo.InsertSerial", cn))
            {
                cmd.CommandType = CommandType.StoredProcedure;
                var pProductId = cmd.Parameters.Add("@ProductId", SqlDbType.Int);
                var pSerial = cmd.Parameters.AddWithValue("@Serial", 
SqlDbType.VarChar); 
                pSerial.Size=50;
                var pSold = cmd.Parameters.AddWithValue("@Sold", SqlDbType.Int);
                foreach (var item in listBox1.Items)
                {
                    pProductId.Value = selectedProductId;
                    pSerial.Value = item.ToString();
                    pSold.Value = 0;
                    Console.WriteLine("Item::: {0}", item.ToString());
                    cmd.ExecuteNonQuery();
                }
                cn.Close();
            }

【讨论】:

  • 成功了,谢谢。
【解决方案2】:

将 using (SqlCommand cmd = new SqlCommand("dbo.InsertSerial", cn)) 放入循环中,这样您每次都会创建一个新命令,否则每次都会向同一命令添加更多参数。

【讨论】:

  • 上面写着ExecuteNonQuery requires an open and available Connection. The connection's current state is closed.' 参考cmd.ExecuteNonQuery();
  • cn.Close() 需要留在外面。我会留下它,因为上面的答案在你的情况下可以完成。在更复杂的场景中,创建一个新命令会更安全。
猜你喜欢
  • 1970-01-01
  • 2011-01-14
  • 2020-06-19
  • 2020-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多