我有这个代码:
using System.Data;
using System.Data.OleDb;
namespace WinFormsApp1
{
public partial class Form1 : Form
{
private int i;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
OleDbConnection conn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0.;Data Source=C:\\Users\\Админ\\OneDrive\\Рабочий стол\\Lab2bz.mdb");
OleDbCommand cmd = new OleDbCommand();
cmd.CommandType = CommandType.Text;
for (int i = 0; i < dataGridView1.Rows.Count - 1; i++)
// cmd.CommandText = "update Tab1 set([Name],[Fname],[Age],[Phone]) where values (?,?,?,?)";
cmd.Parameters.AddWithValue("@Name", dataGridView1.Rows[i].Cells["Name"].Value.ToString());
cmd.Parameters.AddWithValue("@Email", dataGridView1.Rows[i].Cells["Email"].Value.ToString());
cmd.Parameters.AddWithValue("@Date of birth", dataGridView1.Rows[i].Cells["Date of birth"].Value.ToString());
cmd.Parameters.AddWithValue("@Password", dataGridView1.Rows[i].Cells["Password"].Value.ToString());
cmd.Parameters.AddWithValue("@Favorite teams", dataGridView1.Rows[i].Cells["Favorite teams"].Value.ToString());
cmd.Parameters.AddWithValue("@Tickets", dataGridView1.Rows[i].Cells["Tickets"].Value.ToString());
cmd.Parameters.AddWithValue("@ID", dataGridView1.Rows[i].Cells[0].Value);
cmd.CommandText = "UPDATE [User] SET Name=@Name, Email=@Email, Date of birth=@Date of birth, Password=@Password, Favorite teams=@Favorite teams, Tickets=@Tickets WHERE ID=@var";
cmd.Connection = conn;
conn.Open();
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
conn.Close();
System.Windows.Forms.MessageBox.Show("An Item has been successfully added", "Caption", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
conn.Close();
}
}
}
添加
@Email
参数的行会抛出此异常:
System.ArgumentOutOfRangeException:“索引超出范围。必须为非负数且小于集合的大小。Arg_ParamName_Name
循环仅覆盖第一个参数@Name的赋值,后续参数均在循环外。
我该如何解决这个问题?
您缺少 for 循环的左/右大括号。因此,只有第一项(对于
Name
)是循环体的一部分,当您到达第二项(Email
)时,i
变量已经递增到超过了 Rows
的最后一个索引。收藏。
你可以通过添加大括号来解决这个问题,但还有其他改进的空间:
private void button1_Click(object sender, EventArgs e)
{
// Oof, these column names. No professional names columns like this.
string SQL = "UPDATE [User] SET Name=@Name, Email=@Email, [Date of birth]=@Date of birth, Password=@Password, [Favorite teams]=@Favorite teams, Tickets=@Tickets WHERE ID=@ID";
// While I'm here:
// NEVER NEVER NEVER just store a password like that!
// This is too important to do wrong even for practice/learning/proof of concept code!
using var conn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0.;Data Source=C:\\Users\\Админ\\OneDrive\\Рабочий стол\\Lab2bz.mdb");
using var cmd = new OleDbCommand(SQL, conn);
// set up parameters with specfic types *before* the loop starts
// Use *exact* types and lengths from the DB here
cmd.Parameters.Add("@Name", OleDbType.VarWChar, 20);
cmd.Parameters.Add("@Email", OleDbType.VarWChar, 80);
cmd.Parameters.Add("@DOB", OleDbtype.Date);
cmd.Parameters.Add("@Password", OleDbType.Char, 64); // fixed Char, because passwords should be **hashed**, and hashes has fixed sizes
cmd.Parameters.Add("@FavoriteTeams", OleDbType.VarWChar, 120);
cmd.Parameters.Add("@Tickets", OleDbType.VarWChar, 80);
cmd.Parameters.Add("@ID", OleDbType.Integer);
// open connection ONCE at the beginning
conn.Open();
// foreach loop on the rows
foreach(var Row in dataGridView1.Rows)
{ // <--- don't forget the braces!
// now set values for existing parameter objects
cmd.Parameters[0].Value = row.Cells["Name"].Value;
cmd.Parameters[1].Value = row.Cells["Email"].Value;
cmd.Parameters[2].Value = row.Cells["Date of birth"].Value; // ideally, this is an actual Date or DateTime object. If not, considering using Date.Parse() here
cmd.Parameters[3].Value = HashPassword(row.Cells["Password"].Value); // again: passwords MUST (not optional!) be stored **hashed**!
cmd.Parameters[4].Value = row.Cells["Favorite teams"].Value;
cmd.Parameters[5].Value = row.Cells["Tickets"].Value;
cmd.Parameters[6].Value = row.Cells[0].Value; // ideally an actual integer value. If it's a string, considering using int.Parse() or int.TryParse()
cmd.ExecuteNonQuery();
// no need to clear parameters.
// We *want* the existing parameter objects to stay valid!
}
// No need to close the connection ("using" directive takes care of this for us)
}