PDA

View Full Version : کوئری های لازم برای کار با GetChanges



once4ever
یک شنبه 30 اردیبهشت 1386, 20:32 عصر
یه کوئری select نوشتم برای adapter.selectCommand و یک datatable پر کردم

SELECT name, age, num FROM table1 ORDER BY cod
حالا تغییرات دیتا تیبل میخوام update کنم ب

myadap.Update(mydatatable.GetChanges());
خوب اول میگه که باید یک updatecommand به آداپترت بدی. یه updatecommand دادم اما میگه یجاییشو بد نوشتی!
خوب حالا یکی کامل بهم بگه این updatecommand باید چجوری باشه و درمورد delete هم بگه
ممنون

once4ever
یک شنبه 30 اردیبهشت 1386, 21:01 عصر
مشکل با commandbuilder رفع شد

once4ever
دوشنبه 31 اردیبهشت 1386, 18:52 عصر
حالا بجز commandbuilder چجوری میتونیم خودمون بنویسیم؟
مخصوصا وقتی با چند relation داریم کار میکنیم. آیا برای این حالت باز میشه از update استفاده کرد؟

PC2st
دوشنبه 31 اردیبهشت 1386, 22:28 عصر
حالا بجز commandbuilder چجوری میتونیم خودمون بنویسیم؟
به کمک متد GetDeleteCommand، شئ مربوط به Command رو گرفته و توسط خاصیت CommandText ببینید چه دستور DELETE ائی برای اون حالت ایجاد شده. یعنی مثلا:


commandBuilder.GetDeleteCommand().CommandText

once4ever
دوشنبه 31 اردیبهشت 1386, 22:31 عصر
خوب همین کارو کردم ( برای update )
اما هیچ تغییری قبول نمیکنه؟
درضمن من از relation تو سلکت استفاده کردم که تو update میگه نمیتونه همچین انتخابی رو update کنه
راهی داره؟

PC2st
دوشنبه 31 اردیبهشت 1386, 23:12 عصر
میخواید بعد از سلکت کردن، یک رکورد رو از هر دو جدول داخل دیتاست ( دیتاتیبل ) حذف کرده و بعدش با آداپتر، دیتابیس رو اپدیت کنید؟ میشه در مورد دستور سلکت توضیح بدید؟!!

hdv212
دوشنبه 31 اردیبهشت 1386, 23:29 عصر
من خودم شخصا CommandBuilder رو پیشنهاد نمیکنم، مخصوصا برای Relational DataBases.

once4ever
سه شنبه 01 خرداد 1386, 11:30 صبح
من تو سلکت از چندتا relation استفاده کردم.
بعد این اطلاعات داخل datagrid بایند میشه.
1. بعضیها عوض میشن و من میخوام با update اون تغییرات اعمال بشه.اما چون relation داره, قبول نمیکنه.
2. ممکنه سلکت به این شکل باشه:
select ... , a - b AS mins, ...
و میخوام که تو update این مقدار mins که عوض میشه, برای a نوشته بشه و b صفر بشه.

خوب این دوتا با builder انجام نمیشه. پس باید updatecommand خودم بنویسم, اما شکل دستورش چجوری باید باشه؟
(فقط مقدارها عوض میشه و هیچ delete نداره)

من خودم شخصا CommandBuilder رو پیشنهاد نمیکنم، مخصوصا برای Relational DataBases.
خوب از چی استفاده میکنی؟

PC2st
سه شنبه 01 خرداد 1386, 13:53 عصر
برای دو جدولی که ارتباط بین شون در Access ایجاد شده، CommandBuilder کارش رو خوب انجام میده.


کدهای زیر برای تغییر یک فیلد در یک جدول UserTable :


OleDbConnection con = new OleDbConnection( @"Provider = Microsoft.Jet.OLEDB.4.0; Data Source = |DataDirectory|\db.mdb" );
OleDbCommand com = new OleDbCommand( @"SELECT * FROM UserTable", con );
OleDbDataAdapter da = new OleDbDataAdapter( com.CommandText, con );
OleDbCommandBuilder cb = new OleDbCommandBuilder( da );
DataTable dt = new DataTable();
da.Fill( dt );

dt.PrimaryKey = new DataColumn[] { dt.Columns["IDCode"] };

// UserTable تغییر فیلد یک رکورد در جدول
dt.Rows.Find( 4 )["FirstName"] = "John";

da.Update( dt );


جدول UserTable با فیلدهای IDCode ( کلید اصلی ) و FirstName و LastName
و جدول AnyTable با فیلدهای IDCode و BookName هستن.
ارتباط بین فیلد IDCode ( از جدول UserTable ) با IDCode ( از جدول AnyTable ) بصورت یک به چند برقرار شده.




میخوام که تو update این مقدار mins که عوض میشه, برای a نوشته بشه و b صفر بشه.
خوب این دوتا با builder انجام نمیشه.
خوب متوجه نشدم ولی اگه همین تغییرات رو توی دیتاتیبل (دیتاست ) ایجاد کنید، builder هم دستور مربوطه رو ایجاد میکنه.

once4ever
سه شنبه 01 خرداد 1386, 14:39 عصر
ممنون
ولی با اینجور سلکت ببین درست کار میکنه:
select table1.name, table2.age from table1 inner join table2 on table1.id=table2.id
وقتی از این select استفاده کنی, دیگه bulider کار نمیکنه.


خوب متوجه نشدم ولی اگه همین تغییرات رو توی دیتاتیبل (دیتاست ) ایجاد کنید، builder هم دستور مربوطه رو ایجاد میکنه. وقتی توی سلکت من حاصل جمع یا تفریق دوتا فیلد انتخاب کنم, تو update چجوری تغییرشون میده؟ کدومو عوض میکنه؟

PC2st
سه شنبه 01 خرداد 1386, 16:04 عصر
درسته، در صورتی که دستور select اینجوری باشه، ارور میده که :
Dynamic SQL generation is not supported against multiple base tables.
بنظرم نمیشه از commandBuilder برای این حالت استفاده کرد...

با توجه به جدولهائی که در دستور select گفته بودی، با فرض اینکه تمام رکوردهای موجود در جدول table1 با تمام رکوردهای موجود در جدول table2 از لحاظ فیلد id یک تشابه یک به یک داشته باشند ( در غیر این صورت در حین عمل Update از adapter ارور خواهید گرفت )، من فرض کردم که میخوایم کاری کنیم که رکوردی که مقدار id اونها برابر مثلا 48 باشه، محتویات فیلد name از جدول table1 و age از جدول table2 تغییر پیدا کنه. پس دستور UPDATE مورد نیاز :


UPDATE table1, table2
SET table1.name = 'نام جدید', table2.age = سن جدید
WHERE table1.id = 48 AND table2.id = 48




وقتی توی سلکت من حاصل جمع یا تفریق دوتا فیلد انتخاب کنم, تو update چجوری تغییرشون میده؟ کدومو عوض میکنه؟
فکر کنم بر اساس جدولی که داده ازش بیرون کشیده شده... دقیقا نمیدونم! :)

once4ever
سه شنبه 01 خرداد 1386, 16:22 عصر
خوب تا اینجاشو خوب فهمیدی منظورمو
حالا دوست خوب من, من میخوام با update و getchanges اینکارو بکنم.
یه جدول دارم با 20تا رکورد و من نمیدونم کدومو تغییر داده
اینی که شما گفتی, برای حالتی هست که update خودم بنویسم برای هر رکوردی (حلقه تکرار)
اون دستور update ک موقع استفاده از builder درست میشه, از ؟ استفاده کرده بجای مقدار. و منم میخوام بدونم چجوری میتونم همچین کوئری بنویسم.
بنظرم یک سری از parameter و بقیه موارد استفاده میکنه که اگه اینجوری باشه, اصلا صرف نمیکنه (از نظر زمانی و کد نویسی :چشمک: ) از getchanges در این حالت استفاده کرد.
اما اگه بفهمیم چجوری تو این حالت هم جواب میده, خیلی ساده میشه کار
ممنون

PC2st
سه شنبه 01 خرداد 1386, 20:24 عصر
دوست عزیز، دقیقا مطمئن نیستم که منظورتون رو کامل فهمیده باشم، بهرحال این رو نوشتم :


da.UpdateCommand = new OleDbCommand( "UPDATE table1, table2 SET table1.name = @name, table2.age = @age WHERE table1.id = @id AND table2.id = @id", con );
da.UpdateCommand.Parameters.Add( "@name", OleDbType.WChar );
da.UpdateCommand.Parameters.Add( "@age", OleDbType.Integer );
da.UpdateCommand.Parameters.Add( "@id", OleDbType.Integer );
da.UpdateCommand.Parameters["@name"].Value = "NEWNAME";
da.UpdateCommand.Parameters["@age"].Value = 50;
da.UpdateCommand.Parameters["@id"].Value = 1;

برای استفاده دوباره از دستور update، فقط کافیه که سه خط آخر رو با مقادیر جدید، مقدار دهی کنید.
از پارامترها استفاده شده که البته استفاده از ؟ رو برای پارامترها بلد نبودم.

once4ever
سه شنبه 01 خرداد 1386, 22:40 عصر
این برنامه رو ببین
از کدی که نوشتی استفاده کردم اما خطا میگیره
ممنون

PC2st
چهارشنبه 02 خرداد 1386, 22:10 عصر
فایل رو دیدم... به قول شما، مشکل اینه که نمیشه تشخیص داد که کاربر کدوم رکورد رو تغییر داده، پس به فکرم رسید که در حین خواندن اطلاعات توسط SELECT، فیلد id هم گرفته بشه و بصورت یک فیلد مخفی در dataGridView1 قرار داده بشه. بعدش توسط خاصیت SourceColumn، فیلدهای متناظر در دیتاتیبل رو برای متد UPDATE از شئ dataAdapter مشخص میکنیم. متد Update خودش بصورت تکراری، مقادیر جدید رو جایگزین میکنه و احتیاجی به حلقه تکراری نیست. بطور کلی، فقط دو جای برنامت رو تغییر دادم. تغییرات رو در فایل Form1.cs ایجاد کرده و آپلودش کردم...

once4ever
چهارشنبه 02 خرداد 1386, 23:30 عصر
همونطور که گفتی, نکته اصلی در استفاده از SourceColumn بود.
کار بسیار ارزشمندی انجام دادی. حالا یه راه خوب یاد گرفتیم ;)
خیلی ممنون

PC2st
پنج شنبه 03 خرداد 1386, 23:41 عصر
خواهش میکنم... وظیفم بود :)