PDA

View Full Version : سوال: یه مشکل در جست و جو در پایگاه به روش کدنویسی



farzadkamali
سه شنبه 14 مرداد 1393, 17:05 عصر
با سلام
من برای insert می خوام قبلش با یک تابع بررسی کنم که آیا کد عضویتی که کاربر وارد کرده در پایگاه وجود داره یا خیر. اما با مشکل مواجه شدم.
دو تا کلاس دارم یکی به نام dal که تنظیمات پایگاه توشه. و یکی به نام member که توابع و دستورات مربوط به فرم رو توش می نویسم و سپس توی فرمم اون رو فراخونی می کنم.
این تابعیه که توی کلاس member نوشتم.

دستورات و تابع زیر درسته؟ توی تابع زیر چه جوری باید بفهمم که دستور select مقداری رو برگردونده یا خیر.


public void SearchMember(string txtbox)
{
DAL.DatabaseConnection dal = new DAL.DatabaseConnection();
dal.Connect();
string sql = "select * from members where membercode='%' + txtbox + '%' ";
dal.Execute(sql);
dal.DisConnect();


}


برای فراخونی توی فرم هم از دستور
BLLMembers.SearchMember(txtMembercode.Text)
استفاده کردم.
ممنون میشم راهنمایی کنین.

plus
سه شنبه 14 مرداد 1393, 17:15 عصر
خوب اینجا مشخص نیست شما در dal.Execute چی نوشتین؟ ظاهرا از یکی از متدهای Execute مربوط به SqlCommand استفاده کردین. در مواقعی که فقط میخواین ببینید مقداری برگشت داده شده یا نه، میتونید از متد ExecuteNonQuery مربوط به SqlCommand استفاده کنید. خروجی این متد تعداد سطرهای تحت تاثیر اجرای Query هست که اگه 0 باشه یعنی هیچ مقداری SELECT نشده. در ضمن اگه شما میخواین فقط وجود یا عدم وجود رو بررسی کنید نیازی نیست که با * همه فیلدهای رو بی جهت SELECT کنید. میتونید فقط یک فیلد (مثلا Id) رو انتخاب کنید.
--
راه حل دیگه میتونه این باشه که شما بجای * SELECT از (*)SELECT COUNT در Query استفاده کنید و تعداد رکورد هایی که با شرط مورد نظر مطابقت دارن رو دریافت کنید. در این حالت مقدار خروجی (تعداد) رو میتونید با متد ExecuteScalar مربوط به SqlCommand ( با cast کردن خروجی که از نوع object هست به int) بدست بیارین و با 0 مقایسه کنید...

farzadkamali
سه شنبه 14 مرداد 1393, 17:43 عصر
خوب اینجا مشخص نیست شما در dal.Execute چی نوشتین؟ ظاهرا از یکی از متدهای Execute مربوط به SqlCommand استفاده کردین. در مواقعی که فقط میخواین ببینید مقداری برگشت داده شده یا نه، میتونید از متد ExecuteNonQuery مربوط به SqlCommand استفاده کنید. خروجی این متد تعداد سطرهای تحت تاثیر اجرای Query هست که اگه 0 باشه یعنی هیچ مقداری SELECT نشده. در ضمن اگه شما میخواین فقط وجود یا عدم وجود رو بررسی کنید نیازی نیست که با * همه فیلدهای رو بی جهت SELECT کنید. میتونید فقط یک فیلد (مثلا Id) رو انتخاب کنید.
--
راه حل دیگه میتونه این باشه که شما بجای * SELECT از (*)SELECT COUNT در Query استفاده کنید و تعداد رکورد هایی که با شرط مورد نظر مطابقت دارن رو دریافت کنید. در این حالت مقدار خروجی (تعداد) رو میتونید با متد ExecuteScalar مربوط به SqlCommand ( با cast کردن خروجی که از نوع object هست به int) بدست بیارین و با 0 مقایسه کنید...



SqlConnection con;
SqlCommand com;
SqlDataAdapter da;

public DatabaseConnection()
{
con = new SqlConnection();
com = new SqlCommand();
da = new SqlDataAdapter();
com.Connection = con;
da.SelectCommand = com;
}

public void Connect()
{
con.ConnectionString = @"Data Source=.;Initial Catalog=DB;Integrated Security=True";
con.Open();
}

public void DisConnect()
{
con.Close();
}

public void Execute(string SQL)
{
com.CommandText = SQL;
com.ExecuteNonQuery();
}

این دستورات مربوط به اتصال هست.
درسته من از ExecuteNonQuery استفاده کردم. خروجی متد ExecuteNonQuery رو چه جوری میشه بررسی کرد.

mz6488
سه شنبه 14 مرداد 1393, 18:17 عصر
من از روش زیر استفاده میکنم

public static string getItem(string sql)
{
object obj;
string s="";

connect();

cmd.Connection = con;
cmd.CommandText = sql;
obj = cmd.ExecuteScalar();

if (obj== null )
s = "";
else
s =obj.ToString();

disConnect();
return s;
}


بعد میاین شرط میذارین که اگه مقدار استرینگ مخالف "" بود یعنی اینکه همچین کدی وجود داره.تابع رو خلاصه نوشتم

plus
سه شنبه 14 مرداد 1393, 21:05 عصر
این دستورات مربوط به اتصال هست.
درسته من از ExecuteNonQuery استفاده کردم. خروجی متد ExecuteNonQuery رو چه جوری میشه بررسی کرد.
خروجی یک int هست که تعداد سطرهای تحت تاثیر رو برمیگردونه.در این مورد شما، 0 بودن یعنی هیچ رکوردی انتخاب نشده و بیش از 0 هم تعداد رکوردهای انتخاب شده هست.
میتونید متدی که با نام Execute تعریف کردین رو خروجیش رو int کنید و در بدنه ش، مقدار com.ExecuteNonQuery رو برگردونید.
بعد از اون، در متد SearchMember مقدار خروجی Execute رو بررسی کنید که اگه بزرگتر از 0 باشه یعنی حداقل یک سطر انتخاب شده (یک member وجود داره).

mehdiba3
سه شنبه 14 مرداد 1393, 22:02 عصر
سلام
دو روش برای این کار به شما پیشنهاد می کنم.
روش بهتر: یکی از خصوصیات خوب Sql ایجاد فیلد یونیک می باشد.
به طور پیش فرض کلید اصلی یونیک هستش یعنی نمیتونه تکراری باشه. ولی نکته ای وجود داره. فرض تو جدول هم ID داریم که از نوع ایدین تیتی هستش یعنی خودش مقدا میگیره بعد از درج هر کاربر و یک فیلد بنام کد ملی هم داریم که کاربر این فیلد واراد میکنه.
بهترین کار در این موقع این است که درون SQL server بری و فیلد کد ملی رو اندیس بزاری و خاصیت یونیک اون رو فعال کنی.
اینطوری اگه میخواست کاربر رکورد تکراری وارد کنه مثلا تو سیشارپ خطا به وجود میاد و کنترل به کچ میره و شما میتونی اونجا پیغام مربوطه رو برای کاربر نمایش بدی.
روش دیگه وقتی به کار میره که مثلا میخوای فیلد نام و نام خانوادگی تکراری نباشه. برای این کار:
قبل از عمل insert تو جدول میای یک شرط ساده میزاری که :
if not exis (select * from student where name=@name and Family=@family)
که Name@ و Family@ رو به صورت پارامتر برای sql server می فرستی:

اگه شرط بالا بر قرار شد دستورات insert رو شروع کن.

farzadkamali
سه شنبه 14 مرداد 1393, 23:49 عصر
خروجی یک int هست که تعداد سطرهای تحت تاثیر رو برمیگردونه.در این مورد شما، 0 بودن یعنی هیچ رکوردی انتخاب نشده و بیش از 0 هم تعداد رکوردهای انتخاب شده هست.
میتونید متدی که با نام Execute تعریف کردین رو خروجیش رو int کنید و در بدنه ش، مقدار com.ExecuteNonQuery رو برگردونید.
بعد از اون، در متد SearchMember مقدار خروجی Execute رو بررسی کنید که اگه بزرگتر از 0 باشه یعنی حداقل یک سطر انتخاب شده (یک member وجود داره).
به دستور sql گیر میده. به txtbox گیر میده. دستور Sql درسته؟
122031

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


public int execute(string SQL)
{
com.CommandText = SQL;
return com.ExecuteNonQuery();
}




public void SearchMember(string txtbox)
{
dal.Connect();
string sql = "select * from members where membercode='%' + txtbox + '%'";
if (dal.executed(sql)>0)
FMessegeBox.FarsiMessegeBox.Show("وجود دارد");
else
FMessegeBox.FarsiMessegeBox.Show("وجود ندارد");

dal.DisConnect();
}




private void btnOK_Click(object sender, EventArgs e)
{
BLLMembers.SearchMember(txtMembercode.Text);
}


دستوراتی که زدم درسته؟

plus
سه شنبه 14 مرداد 1393, 23:52 عصر
string sql = "select * from members where membercode=" + txtbox;
اگه نوع membercode رشته ای هست:
string sql = "select * from members where membercode='" + txtbox + "'";

farzadkamali
چهارشنبه 15 مرداد 1393, 00:11 صبح
خیلی ممنون عزیز. ارور رفع شد. اما ظاهراً همیشه تعداد سطر ها رو منفی برمی گردونه. چون شرط
if (dal.executed(sql)>0)هیچ وقت برقرار نیست. و فقط شرط if (dal.executed(sql)<0) برقراره.

plus
پنج شنبه 16 مرداد 1393, 17:29 عصر
خیلی ممنون عزیز. ارور رفع شد. اما ظاهراً همیشه تعداد سطر ها رو منفی برمی گردونه. چون شرط
if (dal.executed(sql)>0)هیچ وقت برقرار نیست. و فقط شرط if (dal.executed(sql)<0) برقراره.

ظاهرا من توی اون پست اشتباهی داشتم. ExecuteNonQuery فقط برای دستورات INSERT, UPDATE و DELETE تعداد سطرهای تحت تاثیر رو برمیگردونه.برای دستورات دیگه 1- برمیگردونه.
بنابراین شما برای اینکه تعداد رکوردهای دریافت شده با دستور SELECT رو بدست بیارین باید بجای * SELECT از (*) SELECT COUNT استفاده کنید تا تعداد رکوردها برگرونده بشه و بجای ExecuteNonQuery هم از ExecuteScalar استفاده کنید (و خروجی این متد رو به int تبدیل کنید) تا تعداد برگشت داده بشه.

farzadkamali
جمعه 17 مرداد 1393, 13:56 عصر
ممنون از راهنماییتون. درست شد.
اما دستور فقط یه بار اول اجرا میشه. یعنی یه بار چک میکنه و نتیجه هم درسته. اما وقتی دوباره می خوای چک کنی هیچ جوابی نمیده. یعنی در واقع اصلا دستور اجرا نمیشه. مشکل کجاست؟
شرمنده سوالا زیاد شد.

plus
جمعه 17 مرداد 1393, 15:57 عصر
ممنون از راهنماییتون. درست شد.
اما دستور فقط یه بار اول اجرا میشه. یعنی یه بار چک میکنه و نتیجه هم درسته. اما وقتی دوباره می خوای چک کنی هیچ جوابی نمیده. یعنی در واقع اصلا دستور اجرا نمیشه. مشکل کجاست؟
شرمنده سوالا زیاد شد.
شما باید از Debugging استفاده کنی، BreakPoint بگذاری و دستورات رو تک به تک اجرا کنی تا متوجه بشی مشکل از کجاست.
در نهایت باید به دستورر ExecuteScalar برسی که همیشه جواب میده و اگه دستور SELECT COUNT باشه حتما یک int برمیگردونه