PDA

View Full Version : حرفه ای: متد Update شی DataAdapter



h_arman
شنبه 14 فروردین 1389, 12:53 عصر
من یه بانک sql دارم با حدود 8 میلیون رکورد. هر هفته رکوردهای جدیدی از یه سری فایل متنی خونده میشه و به بانک اصلی اضافه میشه. اگر بخوام برای هر رکورد که میخوام اضافه کنم از یه دستور Insert استفاده کنم زمان خیلی زیادی طول میکشه و سرعت برنامه قابل قبول نیست.


راهکاری که پیدا کردم استفاده از یک Typed Dataset هست که ساختارش دقیقا مثل جدول اصلی توی دیتا بیس باشه. با این روش و تعریف یک sqlDataAdapter و تعریف InsertCommand برای اون مشکل سرعت حل میشه.

اما یه مشکل دیگه:
روی جدول اصلی یه ایندکس یونیک وجود داره که شامل 3 تا از فیلدهاست. یعنی ترکیب این سه تا فیلد نباید تکراری بشه. ولی چون شیء Dataset یک شیء Disconnected هست در موقعی که دارم رکوردها را به Dataset اضافه می کنم اشکالی بوجود نمیاد چون از داده های اصلی جدول بی اطلاعه و وقتی متد Update از شیء sqlDataAdapter اجرا میشه اگر رکورد تکراری تو Dataset باشه خطا میده.

حالا دنبال یه راه حل می گردم که بتونم فقط اون سطرهایی از Dataset را تو جدول اصلی اضافه کنم که تکراری نباشه.

ممنون از وقتی که میذارید

mrsalam
شنبه 14 فروردین 1389, 14:18 عصر
با اجازه اساتید،
به نظر من شما یک متد (بدون استفاده از Typed DataSet)برای بررسی این موضوع تعریف کنید و پس از بررسی اقدام به درج اطلاعت کنید

h_arman
شنبه 14 فروردین 1389, 14:35 عصر
با اجازه اساتید،
به نظر من شما یک متد (بدون استفاده از Typed DataSet)برای بررسی این موضوع تعریف کنید و پس از بررسی اقدام به درج اطلاعت کنید

همونطور که خدمتتون عرض کردم حجم بانک و اطلاعات درون اون بسیار بالاست و این کار بسیار زمان بر است.

اگر به عرایض بنده توجه فرموده باشید من کاری را که مدنظرم بوده انجام داده ام. ولی حالا بدنبال انجام سریعتر و بهینه تر اون هستم.

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

ASKaffash
شنبه 14 فروردین 1389, 14:49 عصر
سلام
با استفاده از DataSet بنظر من شما راهی ندارید چون DataSet یک DataBase کوچولو تقریبا OffLine در سمت Client است و حتی اگر Connection هم قطع شود ربطی به DataBase ندارد مگر اینکه قرار باشد Update صورت پذیرد(وظیفه آداپتور است)

h_arman
شنبه 14 فروردین 1389, 20:56 عصر
سلام
با استفاده از DataSet بنظر من شما راهی ندارید چون DataSet یک DataBase کوچولو تقریبا OffLine در سمت Client است و حتی اگر Connection هم قطع شود ربطی به DataBase ندارد مگر اینکه قرار باشد Update صورت پذیرد(وظیفه آداپتور است)


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

باز هم ممنون

FastCode
شنبه 14 فروردین 1389, 22:11 عصر
insert into table_x(column1, ...) values(value1, ...) union select value1_1,... union select value1_2, ...

mehdi.mousavi
یک شنبه 15 فروردین 1389, 01:21 صبح
روی جدول اصلی یه ایندکس یونیک وجود داره که شامل 3 تا از فیلدهاست. یعنی ترکیب این سه تا فیلد نباید تکراری بشه. ولی چون شیء Dataset یک شیء Disconnected هست در موقعی که دارم رکوردها را به Dataset اضافه می کنم اشکالی بوجود نمیاد چون از داده های اصلی جدول بی اطلاعه و وقتی متد Update از شیء sqlDataAdapter اجرا میشه اگر رکورد تکراری تو Dataset باشه خطا میده.

حالا دنبال یه راه حل می گردم که بتونم فقط اون سطرهایی از Dataset را تو جدول اصلی اضافه کنم که تکراری نباشه. ممنون از وقتی که میذارید

سلام.
آیا رکوردهای موجود در بانک، در DataSet شما وجود داره؟ اگر نداره، چطوری میخواهید اینکارو بدون رجوع به بان انجام بدید؟ (اینم از اون کارهاست ها!). اگرم داره، DataSet امکان تعریف Constraint مشابه روی سه فیلد بصورت توام رو بهتون میده، در نتیجه هنگامیکه دارید رکورد رو به DataSet اضافه می کنید، با Exception ای مواجه میشید که شما رو از عدم برقرار بودن Constraint مربوطه مطلع میکنه.

ضمن اینکه شما فرمودید که استفاده از SQLDataAdapter و InsertCommand مشکلتون رو حل کرده، در حالیکه ادعا میکنید سرعت دستور INSERT قابل قبول نیست! مگه InsertCommand یا Adapter ای که اسم بردید، اطلاعات رو با فرمانی غیر از INSERT به بانک اضافه میکنن؟

لطفا بیشتر توضیح بدید.

موفق باشید.

h_arman
یک شنبه 15 فروردین 1389, 09:37 صبح
آیا رکوردهای موجود در بانک، در DataSet شما وجود داره؟

همونطور که عرض کردم DataSet از جدول اصلی بی اطلاع است. بدلیل حجم بالای اطلاعات امکان لود کردن کل آنها درون DataSet وجود ندارد.



ضمن اینکه شما فرمودید که استفاده از SQLDataAdapter و InsertCommand مشکلتون رو حل کرده،

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



در حالیکه ادعا میکنید سرعت دستور INSERT قابل قبول نیست!

ببخشید. منظورم دستور Insert بود که با استفاده از متد ExecuteNonQuery بود که به ازای هر رکورد بایستی یک بار فراخوانی شود.

امیدوارم تونسته باشم مطلب را کامل توضیح بدم

mehdi.mousavi
یک شنبه 15 فروردین 1389, 10:40 صبح
ببخشید. منظورم دستور Insert بود که با استفاده از متد ExecuteNonQuery بود که به ازای هر رکورد بایستی یک بار فراخوانی شود. امیدوارم تونسته باشم مطلب را کامل توضیح بدم

سلام.
قبل از اینکه برگردم سر اصل مطلب، باید خدمتتون عرض کنم که دستور ExecuteNonQuery میتونه Batch ای از فرامین رو اجرا کنه. شما هرگز نیازی نیست که بازای هر رکورد یکبار ExecuteNonQuery رو فراخوانی کنید. میتونید داده هایی که قصد INSERT کردنشون رو دارید بصورت XML به یک Stored Procedure پاس کنید، و همه رو با هم با یک دستور INSERT در بانک اضافه کنید. ضمن اینکه فکر می کنید SqlDataAdapter چطور کار میکنه؟ اگر شما UpdateBatchSize رو Set نکرده باشید، همین الان هم قاعدتا رکوردها تک تک توی بانک Insert میشن. بر اطمینان از این مساله و بررسی اون، میتونید از SQL Server Profiler استفاده کنید تا ببینید آیا فرضا 5 رکورد که قرار هست INSERT بشه، تک تک INSERT میشه، یا همگی با یک Command...

حالا برگردیم سر سوال اصلی. اگر فرض کنم که با SqlDataAdapter درست کار کرده اید، فرامین بصورت Batch ارسال میشه و خلاصه، مشکلی در پیاده سازی وجود نداره، آخرین چیزی که به ذهنم میرسه استفاده از Partitioned Table هاست. بدین ترتیب که جدول مورد نظر رو به چند بخش بشکونید... این مقاله (http://msdn.microsoft.com/en-us/library/ms345146%28SQL.90%29.aspx) رو بخونید تا با چند و چون این کار آشنا بشید.

موفق باشید.