PDA

View Full Version : کنترل کردن رکورد تکراری



nasimnastaran
سه شنبه 12 شهریور 1392, 00:05 صبح
سلام
من یک جدولی دارم که دارای جند تا فیلد می باشد و اون فیلدی که من می خوام کنترل کنم YearReg و RegNo است که مقادیر آنها به صورت ذیل می باشد :


YearReg RegNo
1350 112
1350 102
1351 110
1350 114
می خواهم در بین تمام رکورد هایی که سال ثبت برابر 1350 می باشد ، برای آپدیت کردن چک کنم آیا مقدار RegNo تکرار می شود یا خیر :



string strQ = @"SELECT COUNT(RegNo) FROM tblRcvLet WHERE YearReg=@s1"
OleDbDataAdapter oda_Edited = new OleDbDataAdapter(strQ, ocn);
oda_Edited.SelectCommand.Parameters.Clear();
oda_Edited.SelectCommand.Parameters.AddWithValue("@s1", txtYearReg.Text);
DataTable dt_Edited = new DataTable();
dt_Edited.Clear();
oda_Edited.Fill(dt_Edited);
if (dt_Edited.Rows.Count > 0)
{
MessageBox.Show("Already Exists!! ");
txtRegNo.Focus();
}
else
{
OleDbCommand ocmd_Edited02 = new OleDbCommand();
ocmd_Edited02.CommandText = @"UPDATE ....
با این وجود برای ویرایش کردن همان رکورد ، نمتوانم مقادیر را نمی توانم تغییر دهم ...
با تشکر

amir200h
سه شنبه 12 شهریور 1392, 01:23 صبح
دوست من شما فقط تعداد اون ستون رو شمارش کردین و ریختین داخل دیتاتیبل. بقیه اطلاعات واکشی نشده که :لبخند:

moeinmohebbi
سه شنبه 12 شهریور 1392, 02:12 صبح
amir2ooh درست میگه select count استفاده کردی، در ضمن واضح تر توضیح بدید مشکلتون رو، فیلدی که قراره تغییر بدید رو چک کنید که کلیداصلی یا اتونامبر نباشه و..

veniz2008
سه شنبه 12 شهریور 1392, 02:17 صبح
سلام
من یک جدولی دارم که دارای جند تا فیلد می باشد و اون فیلدی که من می خوام کنترل کنم YearReg و RegNo است که مقادیر آنها به صورت ذیل می باشد :


YearReg RegNo
1350 112
1350 102
1351 110
1350 114
می خواهم در بین تمام رکورد هایی که سال ثبت برابر 1350 می باشد ، برای آپدیت کردن چک کنم آیا مقدار RegNo تکرار می شود یا خیر :



string strQ = @"SELECT COUNT(RegNo) FROM tblRcvLet WHERE YearReg=@s1"
OleDbDataAdapter oda_Edited = new OleDbDataAdapter(strQ, ocn);
oda_Edited.SelectCommand.Parameters.Clear();
oda_Edited.SelectCommand.Parameters.AddWithValue("@s1", txtYearReg.Text);
DataTable dt_Edited = new DataTable();
dt_Edited.Clear();
oda_Edited.Fill(dt_Edited);
if (dt_Edited.Rows.Count > 0)
{
MessageBox.Show("Already Exists!! ");
txtRegNo.Focus();
}
else
{
OleDbCommand ocmd_Edited02 = new OleDbCommand();
ocmd_Edited02.CommandText = @"UPDATE ....
با این وجود برای ویرایش کردن همان رکورد ، نمتوانم مقادیر را نمی توانم تغییر دهم ...
با تشکر
سلام.
دستورات شما چندین خطا و ایراد داره.
اول اینکه شرط کوئری رو اشتباه نوشتید. چیزی که شما نوشتید میاد یه شمارش براساس سال (YearReg) میزنه در صورتیکه شرط شما باید AND داشته باشه. یعنی همزمان سال و RegNo با هم چک بشن که آیا برای YearReg و RegNo رکوردی ثبت شده یا نه.
مورد بعدی کوئری بهینه این هست که از دستور EXISTS به جای Count استفاده کنید.
دستور Count تا آخرین رکورد جدولت رو پیمایش میکنه ولی دستور EXISTS به محض پیدا کردن یک رکورد با شرط مورد نظر دیگه پیمایش رو انجام نمیده. شما هم دقیقا همینو میخواید. اگر یک رکورد وجود داشته باشه که مقدار YearReg و RegNo اون قبلا ثبت شدن دیگه نباید اون رکورد جدید ثبت بشه. زمانیکه تعداد رکوردهای جدولت زیاد باشه، Count به شدت سرعت رو میاره پایین.
در پایان پیشنهاد میکنم برید سمت استفاده از Stored Procedure ها و همه این کارها رو درون یک SP انجام بدید. (به دلایلی که در تاپیک زیر گفته شده).
موفق باشید.
http://barnamenevis.org/showthread.php?417374-%D8%A2%DB%8C%D8%A7-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-%D8%B1%D9%88%D8%A7%D9%84-%D8%B0%D8%AE%DB%8C%D8%B1%D9%87-%D8%B4%D8%AF%D9%87%28sp%29-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D8%B1%D8%A7-%D9%88%D8%A7%D8%A8%D8%B3%D8%AA%D9%87-%D8%A8%D9%87-%D8%A8%D8%A7%D9%86%DA%A9-%D8%A7%D8%B7%D9%84%D8%A7%D8%B9%D8%A7%D8%AA%DB%8C-%D9%86%D9%85%DB%8C-%DA%A9%D9%86%D8%AF%D8%9F

nasimnastaran
سه شنبه 12 شهریور 1392, 12:38 عصر
با تشکر از پاسخ تان
شاید خوب منظورم را بیان نکردم . ضمناً دیتابیس من هم یک فایل اکسس می باشد . مثال بالا این طور مطرح می کنم :



-----------------------------------------------------
ID FNAME LNAME YearReg RegNo
-----------------------------------------------------
1 Hamed Amiri 1350 108
2 Amir Razavi 1351 113
3 Reza Jahed 1350 116
4 Korosh Rostami 1351 110
5 Mehdi Rad 1350 102
---------------------------------------------------

در اینجا می خوام ردیف ها را ویرایش کنم ، برای ویرایش کردن باید فرم مورد نظر ظاهر شده که مربوط به یک سال مشخص مثلا 1350 ظاهر می شود . در این سال هیچ RegNo نباید یکی باشد . و در مورد بقیه فیلد ها موردی ندارد ( FName و LName ) . که این دستور Sql را نوشتم :



strSql =@"SELECT RegNo WHERE RegNo=@s1 AND YearReg=1350";
oda_Edited.SelectCommand.Parameters.AddWithValue(" @s1", txtRegNo.Text);
.....
.....
DataTable dt_Edited = new DataTable();
dt_Edited.Clear();
oda_Edited.Fill(dt_Edited);
if (dt_Edited.Rows.Count > 0)
{
MessageBox.Show("Already Exists!! ");
txtRegNo.Focus();
}
else
{
OleDbCommand ocmd_Edited02 = new OleDbCommand();
ocmd_Edited02.CommandText = @"UPDATE ....

مشکل اینه هیچ رکوردی را که مربوط به سال 1350 ( در مثال بالا ) نمی توانم ویرایش کنم و میگه قبلا این رکورد وجود دارد .
با تشکر

veniz2008
سه شنبه 12 شهریور 1392, 13:04 عصر
با تشکر از پاسخ تان
شاید خوب منظورم را بیان نکردم . ضمناً دیتابیس من هم یک فایل اکسس می باشد . مثال بالا این طور مطرح می کنم :



-----------------------------------------------------
ID FNAME LNAME YearReg RegNo
-----------------------------------------------------
1 Hamed Amiri 1350 108
2 Amir Razavi 1351 113
3 Reza Jahed 1350 116
4 Korosh Rostami 1351 110
5 Mehdi Rad 1350 102
---------------------------------------------------

مشکل اینه هیچ رکوردی را که مربوط به سال 1350 ( در مثال بالا ) نمی توانم ویرایش کنم و میگه قبلا این رکورد وجود دارد .
با تشکر
طبق رکوردهایی که شما گذاشتبد برای سال 1350 سه رکورد با RegNo های 108 و 116 و 102 موجود هست.
حالا طبق کوئری اگر یکی از این RegNo ها رو وارد کنید بایستی پیغام Already Exist داده بشه (یعنی if شما اجرا بشه) در غیر اینصورت بایستی برنامه وارد else بشه.
شما همیشه (حتی زمانیکه یک RegNo جدید وارد میکنید) وارد if می شید؟
یعنی else شما هیچوقت اجرا نمیشه؟
اگر چنین مشکلی دارید کدتون رو بصورت کامل بذارید. یه عکس هم از داده های جدولتون بگیرید و بذارید.

nasimnastaran
سه شنبه 12 شهریور 1392, 14:18 عصر
تقریباً همیشه همین طور است !
این داده ها از یک Datagrid فرا خوانی می شود و در فرم دیگر نمایش داده می شود ( با دابل کلیک روی هر هردیف از دیتا گرید ) . حالا من می خوام در داخل فرم ظاهر شده ، ویرایش خود را انجام بدهم . چون فیلد های من زیاد است داخل دیتا گرید همه را داخل دیتا گرید قرار ندادم و به خاطر این قضیه همه آنها در داخل فرم نمایش داده می شود .
چون فیلد ها زیاد است من همه فیلد ها را نیاوردم و این یک مثال از برنامه من می باشد :




try
{
if (txtFname.Text == FnameDataGrid && txtLname.Text == LnameDataGrid
&& txtRegNo.Text == RegNoDataGrid && txtYearReg.Text == YearRegDataGrid)
{
OleDbConnection ocn_Edited = new OleDbConnection(ConnectionStringEdited);
OleDbCommand ocmd_Edited = new OleDbCommand();


ocmd_Edited.CommandText = @"UPDATE RegTable SET FNAME=@p1,LNAME=@p2,
YearReg=@p3,RegNo=@p4,
WHERE YearReg=@g1
AND RegNo=@g2";
ocmd_Edited.Parameters.Clear();
ocmd_Edited.Parameters.AddWithValue("@p1", txtFname.Text);
ocmd_Edited.Parameters.AddWithValue("@p2", txtLname.Text);
ocmd_Edited.Parameters.AddWithValue("@p3", txtYearReg.Text);
ocmd_Edited.Parameters.AddWithValue("@p4", txtRegNo.Text);

ocmd_Edited.Parameters.AddWithValue("@g1", YearRegDataGrid);
ocmd_Edited.Parameters.AddWithValue("@g2", RegNoDataGrid);

ocmd_Edited.Connection = null;
ocmd_Edited.Connection = ocn_Edited;

ocn_Edited.Open();
ocmd_Edited.ExecuteNonQuery();
ocn_Edited.Close();

ocmd_Edited.Dispose();
ocn_Edited.Dispose();

MessageBox.Show(" ... This Table Updated ...");

frmShowGrd frmGrd = (frmShowGrd)Application.OpenForms["frmShowGrd"];
frmGrd.boolEdit = true;
frmGrd.FnameDataGrid_1 = txtFname.Text;
frmGrd.LnameDataGrid_1 = txtLname.Text;
frmGrd.YearRegDataGrid_1 = txtYearReg.Text;
frmGrd.RegNoDataGrid_1 = txtRegNo.Text;
this.Close();
}
else
{
OleDbConnection ocn = new OleDbConnection(ConnectionStringEdited);
strSql =@"SELECT RegNo WHERE RegNo=@s1 AND YearReg=@s2";
OleDbDataAdapter oda_Edited = new OleDbDataAdapter(strSql, ocn);
oda_Edited.SelectCommand.Parameters.Clear();
oda_Edited.SelectCommand.Parameters.AddWithValue("@s1", txtRegNo.Text);
oda_Edited.SelectCommand.Parameters.AddWithValue("@s2", txtYearReg.Text);
DataTable dt_Edited = new DataTable();
dt_Edited.Clear();
oda_Edited.Fill(dt_Edited);
if (dt_Edited.Rows.Count > 0)
{
MessageBox.Show("Already Exists!! ");
txtRegNo.Focus();
}
else
{
OleDbCommand ocmd_Edited02 = new OleDbCommand();
ocmd_Edited02.CommandText = @"UPDATE RegTable SET FNAME=@t1,LNAME=@t2,
YearReg=@t3,RegNo=@t4,
WHERE YearReg=@e1
AND RegNo=@e2";

ocmd_Edited02.Parameters.Clear();
ocmd_Edited.Parameters.AddWithValue("@t1", txtFname.Text);
ocmd_Edited.Parameters.AddWithValue("@t2", txtLname.Text);
ocmd_Edited.Parameters.AddWithValue("@t3", txtYearReg.Text);
ocmd_Edited.Parameters.AddWithValue("@t4", txtRegNo.Text);

ocmd_Edited.Parameters.AddWithValue("@e1", YearRegDataGrid);
ocmd_Edited.Parameters.AddWithValue("@e2", RegNoDataGrid);
ocmd_Edited02.Connection = null;
ocmd_Edited02.Connection = ocn;
ocn.Open();
ocmd_Edited02.ExecuteNonQuery();
ocn.Close();
ocmd_Edited02.Dispose();
ocn.Dispose();
MessageBox.Show(" ... This Table Updated ...");

frmShowGrd frmGrd2 = (frmShowGrd)Application.OpenForms["frmShowGrd"];
frmGrd2.boolEdit = true;
frmGrd2.FnameDataGrid_1 = txtFname.Text;
frmGrd2.LnameDataGrid_1 = txtLname.Text;
frmGrd2.YearRegDataGrid_1 = txtYearReg.Text;
frmGrd2.RegNoDataGrid_1 = txtRegNo.Text;
this.Close();
}

dt_Edited.Dispose();
oda_Edited.Dispose();
ocn.Dispose();
}
}
catch (OleDbException e)
{
MessageBox.Show("RegNo is Duplicate !!");

}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}



با تشکر فراوان

veniz2008
سه شنبه 12 شهریور 1392, 17:50 عصر
من هر کاری میکنم نمیتونم منطق کار شما رو پشت این کدها درک کنم.
به خدا هیچ چیز به سادگی کد زدن نیست.
مهم فکر کردن و داشتن دلیل برای هر قطعه کد هست.
وقتی مقادیر رو از گرید میگیرید ایا باز نیاز به مقایسه هست؟ (همون if اول).
با چی دارید مقایسه میکنید؟ شما یه & گذاشتی بین همه مقادیر و بعد میای RegNo رو عوض میکنی. به نظرتون این if تا آخر عمر اجرا میشه؟
فقط دارید لقمه رو دور سرتون میگردونید.
موفق باشید.

nasimnastaran
سه شنبه 12 شهریور 1392, 18:57 عصر
من می خوام به کاربر این اجازه داده شود که مقدار RegNo را هم تغییر بده ، به شرطی که این مقدار با مقدار RegNo دیگری که توی دیتا گرید هست یکی نباشه .

nasimnastaran
چهارشنبه 13 شهریور 1392, 22:52 عصر
موضوع حل شد .
اشکال در دستور sql بود .