PDA

View Full Version : مبتدی: debug شدن بدون error ولی وارد نشدن داده در دیتابیس



mehrdad85
شنبه 04 شهریور 1391, 21:55 عصر
سلام
دوستان خوب برنامه نویس ممنون میشم یه کمکی بکنید مشکلم حل بشه
من یه برنامه ویندوزی نوشتم که خیلی سادس و چیز خاصی نداره اما همیشه ادم از مسائلی که فکر میکنه خیلی سادنو مشکلی ایجاد نمیکنه ضربه میخوره و چیز یاد میگیره
من یه کلاس ایجاد کردم به نام person که نماد شی فرد هستش و چند تا فیلد داده ای داره که مشحصات یه نفر مثل نام و نام خانوادگی و یه id داره و داخل متد ها هم یه متد دارم به نام add که داخل یه فرم در رویداد button click یک دکمه بعد از این که با توجه به مقادیر وارد شده در فرم یک نمونه از شی person میسازه و تابع add را فراخوانی میکنه
برنامه به صورت 3 لایه هستش و برقراری و قطع ارتباط با دیتابیس هم در یه کلاس مجزا نوشته شده
نکته دیگه اینه که دیتابیس هم داخل خود visual درست کردم و sql هستش
مشکل من اینه که وقتی برنامه را debug میکنم همه چیز رو به راهه و هیچ error ای وجود نداره حتی وقتی خط به خط برنامه را trace میکن به هیچ مشکلی بر نمیخوره و اصلا وارد قسمت های catch نمیشه که بخواد پیغامی را نشون بده حتی مقادیر هم monitor میکنم هیچ مشکلی وجود نداره اما نهایتا میبینم که هیچ داده ای داخل دیتابیس وارد نشده
به نظر شما مشکل از کجا میتونه باشه؟
مرسی
اگه توضح بیشتری نیازه بفرمایید تا بیشتر توضیح بدم

باز هم تشکر میکنم بخاطر زمانی که میذارید

Arash_janusV3
شنبه 04 شهریور 1391, 22:00 عصر
این مشکل رو باید به همراه کد مطرح کنید
هیچ کس نمی تونه دقیقا جواب شما را بدهد
احتمالات زیادی وجود دارد

mehrdad85
دوشنبه 06 شهریور 1391, 00:39 صبح
سلام
یعنی هیچ کسی تا حالا به همچین مشکلی بر نخورده یا هیچ احتمالی نمیده و کلا چیزی به ذهن دوستان نمیرسه که راهنمایی بفرمایند؟
واقعا کارمو و مهم تر از اون فکرمو مشغول کرده که چه چیز میتونه باعث همچین اتفاقی بشه که کل پروژه را برده زیر سوال


ممنون میشم یکم وقت بذارید و راهنمایی کنید
مرسی

felfely
دوشنبه 06 شهریور 1391, 06:07 صبح
سلام

یه بار دیگه کانکشن استرینگ رو درست کنین شاید درست شه. اون جایی که تو add new data source ازتون می پرسه یه کپی از دیتابیس رو تو جاهای دیگه انجام بدم بزنین NO
البته با سابقه برنامه نویسی که دارین فکر نکنم اشتباه از این چیزی که گفتم باشه ولی آدمیزاده دیگه.

NIK
دوشنبه 06 شهریور 1391, 08:23 صبح
اگه بتونید برنامه رو ضمیمه کنید، میتونم کمکتون کنم.

mehrdad85
دوشنبه 06 شهریور 1391, 08:41 صبح
سلام
دوست عزیز فایل پروژه را پیوست کردم


ممنون میشم یه وقتی بذارید و یه نگاه بندازید


مرسی

hakim22
دوشنبه 06 شهریور 1391, 08:47 صبح
اول چک کنید که داده هایی که به Datatable اضافه می کنید حتما به Dataadapter با متد Update انجام میدید.

بعدشم خیلی کلی نوشتید و ممکنه هزارتا علت دیگه داشته باشه. کد افزودن یک رکورد به دیتابیس رو بگذارید

NIK
دوشنبه 06 شهریور 1391, 08:57 صبح
این قسمت رو جایگزین کنید و دوباره امتحان کنید. (دقیقا همین کد رو جایگزین کنید. قبل از value یک فاصله نیاز بود)
string sql = "Insert into person (id,name,family)";
try
{
sql += " values ({0},'{1}','{2}')";
sql = string.Format(sql, 1, this.name, this.family);
}
نکته دوم اینکه فیلد id رو به صورت identity کنید تا نیازی نباشه دستی مقدار دهی کنید.
نکته سوم اینکه از این روش برای ارسال پارامتر استفاده نکنید. از SqlParameter استفاده کنید.

Mahmoud.Afrad
دوشنبه 06 شهریور 1391, 09:32 صبح
ببخشید اینو میگم ، از همین کدها توی پروژه استفاده کردید؟!!! آخه توجه کنید به کدتون . شما در فرم نوشتید
private void button1_Click(object sender, EventArgs e)
{
person p = new person();
this.Close();
p.name = this.textBox1.Text;
p.family = this.textBox2.Text;
p.Add();
}
خوب با بسته شدن فرم ، کدهای بعد که مربوط به add هستند اجرا نمیشن که!!!!!!!!!!!!!!




دستور insert هم همونطور که دوستان گفتن خطا داره ، تعداد فیلدها با تعداد valueها مطابقت نداره.

mehrdad85
سه شنبه 07 شهریور 1391, 23:22 عصر
نکته دوم اینکه فیلد id رو به صورت identity کنید تا نیازی نباشه دستی مقدار دهی کنید.

ممنون از دقت و تیز بینیتون . به این واقعا توجه نکرده بودم

نکته سوم اینکه از این روش برای ارسال پارامتر استفاده نکنید. از SqlParameter استفاده کنید.ممنون میشم که راهنمایی بفرمایید که استفاده از این روس برای ارسال پارامتر ها چه مشکلی دارن و یا بعد ها ایجاد میکنن
و اینکه از sqlparamete منظورتون همون یکی یکی add کردن اوناس؟
ببخشید اگه مبتدی میپرسم خوب بلد نیستم دیگه:خجالت:


به هر حال تشکر میکنم بابت وقت و انرژی ای که گذاشتید
سپاس

mehrdad85
سه شنبه 07 شهریور 1391, 23:28 عصر
ببخشید اینو میگم ، از همین کدها توی پروژه استفاده کردید؟!!! آخه توجه کنید به کدتون . شما در فرم نوشتید
private void button1_Click(object sender, EventArgs e)
{
person p = new person();
this.Close();
p.name = this.textBox1.Text;
p.family = this.textBox2.Text;
p.Add();
}
خوب با بسته شدن فرم ، کدهای بعد که مربوط به add هستند اجرا نمیشن که!!!!!!!!!!!!!!

واقعیت اینه که نه
این کدی نیست که داخل پروژه ازش استفاده میکنم چون که خیلی شلوغ بود و زیاد بود و راستش نمیخاستم تمام کار مشخص باشه اینارو به همون ترتیبی که بود طوری که نه منطقش بهم بخورده و نه فیزیکش اینجا آوردم اما قبول دارم از طرفی باید یا کد را کامل آورد یا نیاورد چون ممکنه حین این انتقال اشتباهی صورت بگیره حق با شماس اما خوب چاره ای هم نیست



دستور insert هم همونطور که دوستان گفتن خطا داره ، تعداد فیلدها با تعداد valueها مطابقت نداره.

اگه نیاز داشته باشیم که اطلاعات تنها دو فیلد از یه جدول را تکمیل یا update کنیم چطور باید پارامتر ها را بفرستید
اجازه بدید یه مثال بزنم
مثلا یه جدول که دارای فیلد های 1و 2و 3و 4 هستش و همه فیلد ها به غیر از 1 بتونن مقدار null بگیرن و ما در برنامه بخوایم با یک کوئری فقط فیلد های 1و 3 را مقدار دهی کنیم و داخل جدول اضافه کنیم چطور میتونیمم این کارو انجام بدیم؟


مرسی

mehrdad85
سه شنبه 07 شهریور 1391, 23:44 عصر
سلام
دوست عزیز من هم دقیقا از کدی که شما گذاشته بودید استفاده کردم
هم خودم رفتم و فاصله را رعایت کردم
هم اینکه اصلا برای اینکه تست کنم مشکل دقیقا از کجاس فیلد id در دیتابیس را از نوع nvarchar گرفتم و داخل کد علاوه بر اینکه پارامتر id را هم به متد add اضافه کردم و داخل query هم به عنوان پارمتر اول مثل پرامتر های دیگه رشته بهش پاس دادم اما باز خطا میگیره

حتی یه بار دیگه داخل دیتابس فیلد id را is identity کردم و داخل کد نیز کلا پارمتر id را حذف کردم از دستوراتم
اما هنگام اجرا مشکلی با بقیه پارامتر ها نداره ولی میگه که فیلد id نمیتونه null باشه آخه من که اونو is identity کردم دیگه واسه چی ارور میده
حتی زمانی که به صورت دستی داخل خود دیتابیس یه رکورد درج میکنم نیازی به مقدار دادان به فیلد id نیست و خودش مقدار میگیره مگه اضافه کردن رکورد داخل خود برنامه چیزی متفاوت از اضافه کردن اون به صورت دستی داخل دیتابیس هستش؟

ممنون میشم کمکم کنین

NIK
چهارشنبه 08 شهریور 1391, 10:45 صبح
بازم سلام

خیلی سریع پستهاتون رو خوندم.
فیلد ID در صورتی که Identity باشه دیگه نیاز به مقدار دهی در کوئری نداره. یعنی وقتی میخواید کوئری insert رو بنویسید، فیلد ID رو نادیده بگیرید.
وقتی از SqlParameter استفاده میکنید، امکان هک شدن برنامتون به وسیله حمله اسکیوال اینجکشن وجود نداره.

فرض کنید کاربر به جای یکی از فیلدهای نام یا فامیلی، یه کوئری برای Delete کردن کل رکوردهای جدول استفاده کنه.
این کار امکان پذیره. اما وقتی از SqlParameter استفاده میکنید، دیگه امکان نوشتن کوئری در متغیر ها از بین میره.

منظور از استفاده از SqlParameter دقیقا همون ارسال تک به تک متغیر هاست. برای اینکه راحت تر بتونید کار کنید میتونید از کلاسهای SQL Helper ماکروسافت استفاده کنید.
این کلاسها برای شما که مستقیما از Adapter ها استفاده میکنید، خیلی مفیده.
گرچه پیشنهاد خود من به شما استفاده از Entity Framework است. این مشکلات در این تکنولوژی به طور کامل حل شده و نیازی به ساخت کلاس برای جداول وجود نداره. چون این کار به طور کامل انجام میشه.

و اما مثال برای SqlParameter
ابتدا using System.Data.SqlClient;

و بعد


string sql = "Insert into person (name,family) values (@name,@family)";
SqlCommand scom = new SqlCommand();
SqlParameter[] param = new SqlParameter[]{
new SqlParameter("@name" , this.name),
new SqlParameter("@family" , this.family)
};
scom.Parameters.AddRange(param);

mehrdad85
چهارشنبه 08 شهریور 1391, 14:24 عصر
سلام
دوست عزیز واقعا خوب و عالی توضیح داده بودی مرسی





فیلد ID در صورتی که Identity باشه دیگه نیاز به مقدار دهی در کوئری نداره. یعنی وقتی میخواید کوئری insert رو بنویسید، فیلد ID رو نادیده بگیرید.

من هم دقیقا همینطور فکر میکنم و همین کار را انجام میدم ببینید اصلا میرم داخل دیتابیس و به صورت دستی بدون اینکه id را مقدار بدم به مابقی فیلد ها مقدار میدم و بدون کوچکترین اروری اون سطر به جدول اضافه میشه اما نمیدونم چرا داخل خود برنامه این اتفاق نمیافته و ارور میده ؟

ممکنه باگ داشته باشه و نیازه که یه پروژه جدید درست کنم و کد هامو انتقال بدم ؟البته به سختی!!!!




فرض کنید کاربر به جای یکی از فیلدهای نام یا فامیلی، یه کوئری برای Delete کردن کل رکوردهای جدول استفاده کنه.
این کار امکان پذیره. اما وقتی از SqlParameter استفاده میکنید، دیگه امکان نوشتن کوئری در متغیر ها از بین میره.

منظور از استفاده از SqlParameter دقیقا همون ارسال تک به تک متغیر هاست. برای اینکه راحت تر بتونید کار کنید میتونید از کلاسهای SQL Helper ماکروسافت استفاده کنید.
این کلاسها برای شما که مستقیما از Adapter ها استفاده میکنید، خیلی مفیده.
گرچه پیشنهاد خود من به شما استفاده از Entity Framework است. این مشکلات در این تکنولوژی به طور کامل حل شده و نیازی به ساخت کلاس برای جداول وجود نداره. چون این کار به طور کامل انجام میشه.


دوست عزیز من از یه منبع خوندم که دقیق یادم نیست میشه با یه کاراکتر های خاصی که تو کوئری اضافه میشن از sql injection جلوگیری کرد اما واقعیت هیچ موقع امتحان نکردم
شما چنین چیزی نشنیدی؟
اصلا همچین چیزی امکان پذیره؟

ممنون

mehrdad85
چهارشنبه 08 شهریور 1391, 23:20 عصر
این قسمت رو جایگزین کنید و دوباره امتحان کنید. (دقیقا همین کد رو جایگزین کنید. قبل از value یک فاصله نیاز بود)
string sql = "Insert into person (id,name,family)";
try
{
sql += " values ({0},'{1}','{2}')";
sql = string.Format(sql, 1, this.name, this.family);
}
نکته دوم اینکه فیلد id رو به صورت identity کنید تا نیازی نباشه دستی مقدار دهی کنید.
نکته سوم اینکه از این روش برای ارسال پارامتر استفاده نکنید. از SqlParameter استفاده کنید.

سلام
دوست عزیز من این کد را اضافه کردم اما این ارور را بهم نشون میده
دلیل اونو میدونی چیه؟


System.FormatException: Index (zero based) must be greater than or equal to zero and less than the size of the argument list.
at System.Text.StringBuilder.AppendFormat(IFormatProv ider provider, String format, Object[] args)
at System.String.Format(IFormatProvider provider, String format, Object[] args)
at System.String.Format(String format, Object arg0, Object arg1)
at _؟؟؟؟.person.Add() in C:\Users\؟؟؟؟\Documents\Visual Studio 2008\Projects\؟؟؟\؟؟؟\person.cs:line 23
مرسی

NIK
شنبه 11 شهریور 1391, 09:30 صبح
سلام
دوست عزیز من این کد را اضافه کردم اما این ارور را بهم نشون میده
دلیل اونو میدونی چیه؟


System.FormatException: Index (zero based) must be greater than or equal to zero and less than the size of the argument list.
at System.Text.StringBuilder.AppendFormat(IFormatProv ider provider, String format, Object[] args)
at System.String.Format(IFormatProvider provider, String format, Object[] args)
at System.String.Format(String format, Object arg0, Object arg1)
at _؟؟؟؟.person.Add() in C:\Users\؟؟؟؟\Documents\Visual Studio 2008\Projects\؟؟؟\؟؟؟\person.cs:line 23
مرسی

این خطا مربوط به تعداد یا نوع آرگومانهای ارسالی برای دستور string.Format است
اگه دقیقا همین کد رو اضافه کردی نباید مشکلی باشه. شاید اگه پارامتر 1 رو به "1" تغییر بدی مشکل برطرف بشه.
اگه مشکلت برطرف نشد، پروژه رو آپلود کن تا برطرفش کنم.
موفق باشی.