PDA

View Full Version : مبتدی: درخواست کد عدم ثبت اطلاعات تکراری



ssttss68
دوشنبه 13 بهمن 1399, 19:24 عصر
با سلام خدمت اساتید
بنده یک پروژه نوشتم بابت ثبت اطلاعات مشتری به مشکل بر خوردم و نتونسم از ثبت اطلاعات تکراری جلو گیری کنم .
ممنون میشم راهنمایی کنید .
اینم کد ثبت :
private void btsabt_Click(object sender, EventArgs e)
{
if (tbName.Text == "")
{
MessageBox.Show("نام مشتری الزامی می باشد", "خطا", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}


if (tb_moshtariTableAdapter1.InsertQuery(tbName.Text, tbtell.Text, tbMobile.Text, tbAdres.Text) > 0)
{
MessageBox.Show("ثبت شد");
Close();
}

else
MessageBox.Show("نام مشتری را کامل کنید");

}

the king
دوشنبه 13 بهمن 1399, 22:34 عصر
با سلام خدمت اساتید
بنده یک پروژه نوشتم بابت ثبت اطلاعات مشتری به مشکل بر خوردم و نتونسم از ثبت اطلاعات تکراری جلو گیری کنم .
ممنون میشم راهنمایی کنید .
اینم کد ثبت :
private void btsabt_Click(object sender, EventArgs e)
{
if (tbName.Text == "")
{
MessageBox.Show("نام مشتری الزامی می باشد", "خطا", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}


if (tb_moshtariTableAdapter1.InsertQuery(tbName.Text, tbtell.Text, tbMobile.Text, tbAdres.Text) > 0)
{
MessageBox.Show("ثبت شد");
Close();
}

else
MessageBox.Show("نام مشتری را کامل کنید");

}




یک چیزی شبیه به این. کد دقیق به شمای جدول و روال ارتباط در برنامه شما داره.

var cmd = tb_moshtariTableAdapter1.Adapter. InsertCommand.Clone();
cmd.Connection.Open();
cmd.CommandText = "SELECT Name FROM dbo.tb_moshtari WHERE Name=@Name";
cmd.Parameters.Clear();
cmd.Parameters.Add( new System.Data.SqlClient.SqlParameter ("Name", tbName.Text.Trim()));
var name = cmd.ExecuteScalar();
cmd.Connection.Close();
if (name != null)
{
MessageBox.Show("یک مشتری با این نام قبلا به ثبت رسیده است", "خطا", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}

ssttss68
سه شنبه 14 بهمن 1399, 07:41 صبح
ممنون از راهنمای تون ولی این کد برای من کارساز نبود .
من پروژه رو با sql و سی شارپ نوشتم و ضمیمیه کردم که در صورت امکان بررسی بشه و ایراد کار مشخص بشه .
درخواستم اینه که درصورتی تو فرم مشتری ،نام مشتری و تو فرم کالا ،نام کالا و برند تکراری بود موقع ثبت خطا بده .
ممنون میشم اساتید راهنمایی کنن .

ssttss68
سه شنبه 14 بهمن 1399, 07:47 صبح
ممنون از راهنمای تون ولی این کد برای من کارساز نبود .
من پروژه رو با sql و سی شارپ نوشتم و ضمیمیه کردم که در صورت امکان بررسی بشه و ایراد کار مشخص بشه .
درخواستم اینه که درصورتی تو فرم مشتری ،نام مشتری و تو فرم کالا ،نام کالا و برند تکراری بود موقع ثبت خطا بده .
ممنون میشم اساتید راهنمایی کنن .
البته نام کاربری و رمز عبور :admin . admin

the king
سه شنبه 14 بهمن 1399, 14:41 عصر
ممنون از راهنمای تون ولی این کد برای من کارساز نبود .
من پروژه رو با sql و سی شارپ نوشتم و ضمیمیه کردم که در صورت امکان بررسی بشه و ایراد کار مشخص بشه .
درخواستم اینه که درصورتی تو فرم مشتری ،نام مشتری و تو فرم کالا ،نام کالا و برند تکراری بود موقع ثبت خطا بده .
ممنون میشم اساتید راهنمایی کنن .

چند تا مورد رو در نظر بگیرید :
مورد اول اینکه کد کلاس FormLogin رو ببینید، در کد btsabt_Click برای SqlConnection مقدار Connection String رو صریحا مشخص کرده اید که ارتباطی با تنظیمات پروژه نداره و مستقل ئه.
اینکار رو نکنید، Connection String رو همیشه از یک منبع مشخص بخونید که بدون نیاز به ویرایش بخش های مختلف کد برنامه بشه تغییرش داد.
در جاهای مختلف مقدارش رو صریحا ننویسید، تغییرش نیازی به ویرایش کد نداشته باشه.
مخصوصا که در Properties.Settings.Default.DB1ConnectionString مقدارش رو دارید (منوی Project > test 3 Properties... > Settings)
و نیازی نیست که بخواهید مجددا مقدارش رو وارد کنید.

var con = new SqlConnection( Properties.Settings.Default. DB1ConnectionString);

test 3.exe رو در پوشه pro 99-11-13-v0\test 3\bin\Debug پیدا کنید، کنارش یک فایل متنی test 3.exe.config هست، اونجا ذخیره میشه.

private void btsabt_Click(object sender, EventArgs e)
{
var con = new SqlConnection( Properties.Settings.Default. DB1ConnectionString);
var com = new SqlCommand();
int i = 0;


مورد دوم اینکه هیچوقت مقدار ورودی کاربر رو مستقیما وارد کد SQL نکنید، چون برنامه تون نسبت به SQL Injection آسیب پذیر میشه.
کوئری شما این بوده :

"SELECT COUNT(*) FROM tb_login WHERE UserName='" + username.Text + "' AND Password='" + Password.Text + "'"
اگر کاربر به عنوان نام کاربری بنویسه x و بجای رمز عبور بنویسه y' OR 'a'='a شما همچین کوئری ای می سازید :


SELECT COUNT(*) FROM tb_login WHERE UserName='x' AND Password='y' OR 'a'='a'

و همیشه این WHERE برقراره و کاربر بدون نیاز به دانستن رمز عبور میتونه وارد بشه.

152986

برای اینکه جلوی SQL Injection ها رو بگیرید می توانید از Parameters استفاده کنید :

com = new SqlCommand("SELECT COUNT(*) FROM tb_login WHERE UserName=@UserName AND Password=@Password", con);
com.Parameters.Add( new SqlParameter( "UserName", username.Text));
com.Parameters.Add( new SqlParameter( "Password", Password.Text));


مورد بعدی اینکه شما ()i = (int)com.ExecuteScalar رو داخل شرط if (con.State == ConnectionState.Closed) قرار داده اید، نباید ربطی به بسته بودن con داشته باشه، بیرون شرط قرارش بدهید :

if (con.State == ConnectionState.Closed)
{
con.Open();
}
i = (int)com.ExecuteScalar();
con.Close();



private void btsabt_Click(object sender, EventArgs e)
{
if (tbName.Text.Trim() == string.Empty)
{
MessageBox.Show("نام مشتری الزامی می باشد", "خطا", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}
var con = new SqlConnection( Properties.Settings.Default. DB1ConnectionString);
var com = new SqlCommand("SELECT COUNT(*) FROM [tb-moshtari] WHERE [name moshtari]=@Name", con);
com.Parameters.Add( new SqlParameter("Name", tbName.Text));
if (con.State == ConnectionState.Closed)
{
con.Open();
}
var i = (int)com.ExecuteScalar();
con.Close();
if (i > 0)
{
MessageBox.Show( "یک مشتری با این نام قبلا به ثبت رسیده است", "خطا", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}
if (tb_moshtariTableAdapter1. InsertQuery( tbName.Text, tbtell.Text, tbMobile.Text, tbAdres.Text) > 0)
{
MessageBox.Show("ثبت شد");
Close();
}
else
{
MessageBox.Show("نام مشتری را کامل کنید");
}
}

ssttss68
چهارشنبه 15 بهمن 1399, 14:51 عصر
ممنون از راهنمایی دقیقتون .
نکته های جالبی گفته بودید که واقعا کار ساز بودو مشکل من حل شد.
یک مشکل دیگه در ادامه این برنامه پیش امد . من از همین کد البته با کمی نغییر برای قسمت ویرایش هم استفاده کردم .
ولی وقتی دکمه ثبت ویراش رو می زنم برنامه خطا میده.
عکس خطا روضمیمه کردم .
ممنون می شم راهنمایی کنید.
152988

ssttss68
چهارشنبه 15 بهمن 1399, 14:55 عصر
عکس خطا موقع زدن دکمه ویرایش

the king
چهارشنبه 15 بهمن 1399, 15:08 عصر
عکس خطا موقع زدن دکمه ویرایش
پارامتر ها رو بدون بکارگیری فاصله تعریف کنید، مثلا بجای name mahsol]=@name mahsol] بنویسید name mahsol]=@namemahsol]
و SqlParameter ئه "namemahsol@" رو تعریف کنید، نه "name mahsol@"
اون فاصله باعث میشه که mahsol بشه یک عبارت مجزا از name@ و دنبال name@ ای بگرده که تعریف نشده.

ssttss68
پنج شنبه 16 بهمن 1399, 08:46 صبح
ممنون از راهنماییتون.
کاری که گفتید رو انجام دادم و جواب داد ولی چون من دو تا فیلد دارم که باید هر دو رو چک کنه که تکراری نباشه موقع زدن دکمه ثبت ویرایش مجبورم هر دو فیلد رو ویرایش کنم.
اگر فقط یکی رو ویرایش کنم و دومی دست نخورده بمونه خطاتکراری بودن میده .

ssttss68
دوشنبه 20 بهمن 1399, 11:44 صبح
ممنون از راهنماییتون.
کاری که گفتید رو انجام دادم و جواب داد ولی چون من دو تا فیلد دارم که باید هر دو رو چک کنه که تکراری نباشه موقع زدن دکمه ثبت ویرایش مجبورم هر دو فیلد رو ویرایش کنم.
اگر فقط یکی رو ویرایش کنم و دومی دست نخورده بمونه خطاتکراری بودن میده .
کسی از اساتید نیست بتونه کمک کنه !!!!!!!!!!!!

Mahmoud.Afrad
پنج شنبه 23 بهمن 1399, 01:30 صبح
کسی از اساتید نیست بتونه کمک کنه !!!!!!!!!!!!

توی ویرایش با این کدی که نوشتید بدون تغییر با زدن دکمه ویرایش با همین خطا روبرو میشید، علت هم اینه که خود همین رکورد شمرده میشه. در قسمت شرط کوئری ، شرطی رو اضافه کنید که کلیداصلی مخالف مقدار رکوردی باشه که دارید ویرایش میکنیدش.

برای چک کردن وجود مقدار هم از راهی غیر از شمردن استفاده کنید مثل استفاده از exists و یا یونیک کردن ستون.

ssttss68
پنج شنبه 23 بهمن 1399, 07:38 صبح
توی ویرایش با این کدی که نوشتید بدون تغییر با زدن دکمه ویرایش با همین خطا روبرو میشید، علت هم اینه که خود همین رکورد شمرده میشه. در قسمت شرط کوئری ، شرطی رو اضافه کنید که کلیداصلی مخالف مقدار رکوردی باشه که دارید ویرایش میکنیدش.

برای چک کردن وجود مقدار هم از راهی غیر از شمردن استفاده کنید مثل استفاده از exists و یا یونیک کردن ستون.
سلام . ممنون از راهنماییتون
ولی متاسفانه نتونستم کد رو تغییر بدم . اگه بتونید کد رو بنویسید ممنون می شم .

ssttss68
دوشنبه 27 بهمن 1399, 11:43 صبح
هیچ کدوم از اساتید نظری ندارن ؟؟؟؟؟؟؟؟؟؟؟؟