C#参数化查询X需要提供参数Y,但未提供

3
我在尝试更新SQL Server数据库中的值时遇到了一些问题。
我有以下DataGridView: DataGridView-Data 当我点击下面的保存按钮时,我想更改复选框并将布尔值写回SQL Server。
我使用设计器将BindingSource添加到SQL Server表中,这样可以很好地读取和显示来自SQL的值。
保存按钮包含以下代码:
private void cmdChange_Click(object sender, EventArgs e)
{
    var PID = new SqlParameter("@PID",SqlDbType.Int);
    var Programm = new SqlParameter("@Installed",SqlDbType.Int);

    string prgUpdate = "UPDATE Programme SET Installed=@Installed WHERE PID=@PID";

    using (SqlConnection update = new SqlConnection(altdbconnect))
    {
        update.Open();

        for (int i = 0; i < dGVUpdates.Rows.Count; i++)
        {
            using (SqlCommand insert3 = new SqlCommand(prgUpdate, update))
            {
                insert3.Parameters.AddWithValue("@PID", dGVUpdates.Rows[i].Cells["pIDDataGridViewTextBoxColumn1"].Value);
                insert3.Parameters.AddWithValue("@Installed", dGVUpdates.Rows[i].Cells["installedDataGridViewTextBoxColumn"].Value);
                insert3.ExecuteNonQuery();
            }
        }

        update.Close();
    }

    dGVUpdates.Update();
    dGVUpdates.Refresh();
}

但是当我点击保存在DGV中更改的值时,出现了以下错误:

附加信息:参数化查询'(@PID nvarchar(4000),@Installed nvarchar(4000))UPDATE Programme '期望提供未提供的参数“ @PID”。

我将所有使用的语句与另一个DataGridView进行了比较。它们看起来一样。 就像链接图片中显示的那样,有一个参数@PID设置。 pIDDataGridViewTextBoxColumn1列是由设计师生成的。这是PID的列。
我将其与正常工作的此列进行了比较。找不到区别:
var kdNummer = new SqlParameter("@Kundennummer", SqlDbType.Int);
var kdName = new SqlParameter("@Kundenname", SqlDbType.VarChar);
var kdMail = new SqlParameter("@Kundenmail", SqlDbType.VarChar);
var kdTele = new SqlParameter("@Telefon", SqlDbType.VarChar);
var kdOffen = new SqlParameter("@Offen", SqlDbType.Int);

string kdquery = "INSERT INTO gfcKunden VALUES (@Kundennummer, @Kundenname, @Kundenmail, @Telefon, @Offen)";

using (SqlConnection updatedb = new SqlConnection(altdbconnect))
{
    updatedb.Open();

    for (int i = 0; i < dataGridView1.Rows.Count; i++)
    {
        try
        {
            using (SqlCommand insert = new SqlCommand(kdquery, updatedb))
            {
                insert.Parameters.AddWithValue("@Kundenname", dataGridView1.Rows[i].Cells["Kundenname"].Value);
                insert.Parameters.AddWithValue("@Kundennummer", dataGridView1.Rows[i].Cells["Kundennummer"].Value);
                insert.Parameters.AddWithValue("@Kundenmail", dataGridView1.Rows[i].Cells["Kundenmail"].Value);
                insert.Parameters.AddWithValue("@Telefon", dataGridView1.Rows[i].Cells["Telefon"].Value);
                insert.Parameters.AddWithValue("@Offen", 0);

                insert.ExecuteNonQuery();
            }
        }
        catch { }
    }

    updatedb.Close();
}

SQL Server表的截图:

SQL-Table


1
也许你的 dGVUpdates.Rows[i].Cells["pIDDataGridViewTextBoxColumn1"].Value 是空的? - SᴇM
1
你为什么一直创建参数变量然后又忽略它们? - LarsTech
你的错误信息看起来很奇怪.. 你修改过吗?还是这个错误信息是调试器生成的原始信息? - Kay Lee
不,错误信息并非由我编辑。这是由调试器生成的。 - JasonX2000
1个回答

1
正如LarsTech所评论的那样,变量声明的所有行都是无意义的。 这意味着下面的行没有任何作用。
var PID = new SqlParameter("@PID",SqlDbType.Int);
var Programm = new SqlParameter("@Installed",SqlDbType.Int);

然而,上述更改可能不会影响结果。

但是,正如您所看到的,您对数据类型有点困惑。在您的错误消息中,@PID nvarchar(4000) 表示 PID 列被设计为使用文本数据。但是您在上面声明它为 Int。ID 通常是数字,但是您的 SQL 数据库 PID 列在过去由某人设计为 nvarchar。但是,C# 语言可以轻松地将数字转换为文本和文本转换为数字。这没有问题。

我建议更具体地使用,

insert3.Parameters.Add(new SqlParameter("@PID", SqlDbType.NVarChar));
insert3.Parameters["@PID"].Value= dGVUpdates.Rows[i].Cells["pIDDataGridViewTextBoxColumn1"].Value.ToString();

首先,查看每个列使用的数据类型,并分别使用正确的数据类型。此外,您需要确认kdNummer列,因为您在代码中将其声明为Int(但再次没有意义),但您正在插入文本。如果您想将文本值转换为Int数字,则需要执行此操作。
insert.Parameters.AddWithValue("@Kundennummer", Convert.ToInt32(dataGridView1.Rows[i].Cells["Kundennummer"].Value));

希望这有所帮助...

嗨,我添加了一个 SQL 表的截图。PID 声明为整数并作为主键。 - JasonX2000
我添加了Convert.ToInt32语句,这有所帮助。 你是对的,我感到困惑,因为我将SQL表声明为整数和主键,但错误显示参数为nvarchar(4000)。 设计师在从SQL读取数据时是否搞错了什么? 就像我说的,第一次使用参数时它们运行良好。唯一的区别是,我通过代码填充了第一个DGV而不是通过设计师。 - JasonX2000
我看到了截图。我只使用代码,不熟悉设计师。如果你想使用设计师,似乎需要了解设计师的工作原理。我也为你的问题点赞了。祝你有美好的一天! - Kay Lee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接