数据库更新错误(如果存在单个数据则更新,如果存在多个不更新)

数据库更新错误(如果存在单个数据则更新,如果存在多个不更新)

问题描述:

UGIcon.Open();
           cmd = new SqlCommand("select * from purchase", UGIcon);
           SqlDataReader s = cmd.ExecuteReader();
           if (s.Read())
           {
               if (toolStripTextBox1.Text != s["cm"].ToString())
               {
                   MessageBox.Show("Please check the name");
               }
               else
               {
                   if (textBox2.Text == "")
                   {
                       errorProvider1.SetError(textBox2, "Provide Owner name");
                   }
                   else if (textBox3.Text == "")
                   {
                       errorProvider1.SetError(textBox3, "Provide Address");
                   }



                   else
                   {


                       int a = 0, b = 0, c = 0;

                       if (!int.TryParse(textBox5.Text,
                                           System.Globalization.NumberStyles.Integer,
                                           System.Globalization.CultureInfo.CurrentUICulture,
                                           out a))
                       {
                           MessageBox.Show("u need to enter value");
                       }

                       else if (!int.TryParse(textBox9.Text,
                                           System.Globalization.NumberStyles.Integer,
                                           System.Globalization.CultureInfo.CurrentUICulture,
                                           out b))
                       {
                           MessageBox.Show("u entered greater value");
                       }
                       else if (b > a)
                       {
                           MessageBox.Show("ur amount greater then total");

                       }
                       else
                       {
                           c = a - b;
                           textBox10.Text = c.ToString(
                               System.Globalization.CultureInfo.CurrentUICulture);
                           long status = Convert.ToInt64(textBox10.Text);
                           if (status == 0)
                           {
                               textBox4.Text = "paid";
                           }
                           else
                           {
                               textBox4.Text = "pending";
                           }
                           // UGIcon.Open();
                           cmd = new SqlCommand("update purchase set om='" + textBox2.Text + "', address='" + textBox3.Text + "', phone='" + maskedTextBox1.Text.ToString() + "',baled='" + numericUpDown2.Value + "',paid='" + textBox9.Text + "',status='" + textBox4.Text + "',balance='" + textBox10.Text + "' where cm='" + toolStripTextBox1.Text + "'", UGIcon);
                           SqlDataReader dr;
                           dr = cmd.ExecuteReader();

                           MessageBox.Show("Details has been updated sucessfully", "Update Window", MessageBoxButtons.OK, MessageBoxIcon.Information);

                       }


                   }

               }

               UGIcon.Close();


           }





如果我更新,如果有一个记录的存在工作...如果我添加另一条记录并更新然后请检查名称消息框显示...不更新



if i update if the presence of one record its working... if i added another record and update then "please check the name" messagebox displaying... not updating

你没有解释什么是逻辑在你的代码背后,你想要实现什么?

该消息只是意味着文本框中的文本与从数据库获得的第一行中cm列中的文本不同。

为什么要查询购买中的所有记录然后只使用第一个结果?



我只是在猜测但是试图改变第一个查询:

You did not explain what is the logic behind your code, what are you trying to achieve?
That message simply means that text in your textbox is different from text in ''cm'' column in first row you get from database.
Why are you querying all records from ''purchase'' and then using just first result?

I''m just guessing but try to change first query:
cmd = new SqlCommand(string.Format("select * from purchase where cm = '{0}'", toolStripTextBox1.Text), UGIcon);





秒ond查询应该用 cmd.ExecuteNonQuery()运行。



最重要的是,你永远不应该写查询通过连接字符串。

尽可能使用参数化查询,例如:



Second query should be run with cmd.ExecuteNonQuery().

And most important, you should never write queries by concatenating strings.
Always use parametrized queries when possible, something like:

cmd = new SqlCommand("select * from purchase where cm = @cm", UGIcon);
cmd.Parameters.Add(new SqlParameter("@cm", toolStripTextBox1.Text);





您可以在此处找到关于此主题的大量示例codeproject。



You can find a lot of examples on this subject here on codeproject.


进一步对sjelen的回答和之前的评论
Further to sjelen''s answer and earlier comment
引用:

有这么多错误在这段代码中的内容,我不知道从哪里开始。

There are so many wrong things in this code, I wouldn''t know where to begin.

(我碰巧同意)我认为我在练习我的重构和同行评审技巧时会有一点点裂缝。代码我''在这里张贴可能并不完美,但它展示了更好的和/或替代性的方法。看看我添加的评论,以了解我为什么建议。



(which I happen to agree with) I thought I''d have a crack at practising my refactoring and peer review skills. The code I''m posting here may not be perfect but it demonstrates better and/or alternative ways of going about it. Look at the comments I''ve added to understand why I''m suggesting things.

// Do your validations first and flag ALL of the errors at the same time
// and be consistent in the way you are reporting errors to the user
// Personally I would put these into a separate function
bool errorsFound = false;  // or you could have int errorsFound = 0; and increment
if (textBox2.Text == "")
{
    errorProvider1.SetError(textBox2, "Provide Owner name");
    errorsFound = true;
}
if (textBox3.Text == "")
{
    errorProvider1.SetError(textBox3, "Provide Address");
    errorsFound = true;
}
int a = 0, b = 0, c = 0;
// using System.Globalization; means you can keep your code 
// less cluttered and easier to read
if (!int.TryParse(textBox5.Text, NumberStyles.Integer,
                    CultureInfo.CurrentUICulture, out a))
{
	errorProvider1.SetError(textBox5, "u need to enter value");
	errorsFound = true;
}
if (!int.TryParse(textBox9.Text, NumberStyles.Integer,
                    CultureInfo.CurrentUICulture, out b))
{
	errorProvider1.SetError(textBox9, "u need to enter value");
	errorsFound = true;
}
if (b > a)
{
	errorProvider1.SetError(textBox9, "ur amount greater then total");
	errorsFound = true;
}
// Check they''ve entered a name before searching the database!
if(toolStripTextBox1.Text.Trim() == "")
{
	errorProvider1.SetError(toolStripTextBox1, "enter a name");
	errorsFound = true;
}
if(errorsFound)
{
	MessageBox.Show("Please correct the errors indicated");
	return;  // get out of here if there are errors -- keeps indenting to a minimum
}
// End of Validations
// Get used to putting error handling in straight away
try
{

	UGIcon.Open();
	// See sjelen''s solution - use a parameterised query
	// I also prefer to make it clear which commands are read and which are write
	SqlCommand cmdRead = new SqlCommand("select * from purchase where cm = @cm", UGIcon);
	cmdRead.Parameters.Add(new SqlParameter("@cm", toolStripTextBox1.Text));
	SqlDataReader s = cmd.ExecuteReader();
	bool readSuccess = s.Read();
	if(readSuccess && s.HasRows)
	{
		c = a - b;
		textBox10.Text = c.ToString(CultureInfo.CurrentUICulture);
		long status = Convert.ToInt64(textBox10.Text);
		
		// I happen to like the ternary operator so I would have done this ...
		textBox4.Text = (status == 0) ? "paid" : "pending";

		SqlCommand cmdWrite = new SqlCommand("update purchase set om=''@p1'',address='' @p2'', phone=''@p3'',baled=''@p4'',paid=''@p5'',status=''@p6'',balance=''@p7'' where cm=''@cm''", UGIcon);
		cmdWrite.Parameters.Add(new SqlParameter("@p1", textBox2.Text));
		cmdWrite.Parameters.Add(new SqlParameter("@p2", textBox3.Text));
		cmdWrite.Parameters.Add(new SqlParameter("@p3", maskedTextBox1.Text));
		cmdWrite.Parameters.Add(new SqlParameter("@p4", numericUpDown2.Value.ToString()));
		cmdWrite.Parameters.Add(new SqlParameter("@p5", textBox9.Text));
		cmdWrite.Parameters.Add(new SqlParameter("@p6", textBox4.Text));
		cmdWrite.Parameters.Add(new SqlParameter("@p7", textBox10.Text));
		cmdWrite.Parameters.Add(new SqlParameter("@cm", toolStripTextBox1.Text));
		
		// You''re using the wrong method to update - do this instead
		int rowsUpdated = cmdWrite.ExecuteNonQuery();

		// Only 1 row should have been updated
		if(rowsUpdated == 1)
			MessageBox.Show("Details has been updated sucessfully", "Update Window", MessageBoxButtons.OK, MessageBoxIcon.Information);
		else if(rowsUpdated > 1)
			MessageBox.Show("Duplicate rows on database", "Update Window", MessageBoxButtons.OK, MessageBoxIcon.Information);
		else
			MessageBox.Show("Details have not been updated ", "Update Window", MessageBoxButtons.OK, MessageBoxIcon.Information);
	}
	else
	{
		MessageBox.Show("Name not found on database", "Update Window", MessageBoxButtons.OK, MessageBoxIcon.Information);
	}
	
	UGIcon.Close();
}
catch (Exception ex)
{
	// you can check for specific exception types here
	// and possibly show meaningful messages
	throw;
	// Never just do nothing in a catch block - it''s a very 
	// bad habit to just "swallow" errors
}