PDA

View Full Version : خواندن متغیر گلوبال در داخل حلقه While مربوط به کرسور !



Babak-Aghili
چهارشنبه 14 تیر 1385, 10:12 صبح
سلام بر حضرات آیات. :لبخند:

البته هنوز خودم دست به کد نشده ام که عملا تست کنم ، ولی قبلش میخواستم با شما هم مشورت کرده باشم ::

یک حلقه while داریم مربوط به کرسور ... حالا میخوام هربار که کرسور حلقه را اجرا میکنه و به سراغ رکورد بعدی میره ، مثلا شماره اون رکورد را داشته باشم و در همین حین که کرسور در داخل حلقه درحال انجام وظایفش هست ، من هم بتونم اون شماره رکورد را در داخل برنامه ام بخونم و ازش استفاده کنم ... ( واضح بود سوالم یا نه ؟ :گیج:)

( بابا ! اون متغیر شماره رکورد جاری را واسه درست کردن و نشون دادن یک Progress Bar لازم دارم دیگه !! )

ایده ای ؟ نظری ؟ پیشنهادی ؟ چیزی ؟

خیلی ممنون از راهنمایی شما .

majid_afra222
چهارشنبه 14 تیر 1385, 16:36 عصر
سلام
اینجوری امکان نداره. چون به ازای هر درخواست از DBMS فقط یه مقدار از طرف DBMS برگردونده میشه. یا موفقیت آمیزه و جواب میگیری یا اینکه یه خطا دریافت میکنی، اینکه وسط کار هم یه چیزی بگه نداره، وقتی تموم شد تازه میفهمی چه خبر بوده.

Babak-Aghili
چهارشنبه 14 تیر 1385, 18:45 عصر
یه ایده دیگه :: یک SP‌ داشته باشم داخل حلقه ی While که کارش افزودن به یک کانتر و برگردوندن اون به برنامه باشه ...

میشه اینطوری ؟

حضرات لطفا یک فکر بکر بکنند .. مساله حیاتیه

Kamyar.Kimiyabeigi
چهارشنبه 14 تیر 1385, 20:36 عصر
شما نمیتونین این حلقه رو در داخل Application پیاده سازی کنین؟
چون اگر بخواین cursor بنویسید این cursor در session خودش کارش رو انجام میده و اگر بخواهین از Temp table و یا از Counter استفاده کنین در واقع باید داخل Application بوسیله یک Timer به Database سر بزنین و مقدار اون temp Table و یا Counter رو بخونین. در واقع این Cursor حاصل یک select هست که به نظر من این Select رو Sp کنین و داخل application اونو execute کنین و بر اساس Record Count شما میتونین progres bar تونو مقدار دهی کنین

AminSobati
جمعه 16 تیر 1385, 11:17 صبح
بابک جان تا زمانی که یک Script (مثلا یک SP) در SQL Server کارش به پایان نرسیده، چیزی رو به Client برنمیگردونه.
شاید برای منظور شما، این بهتر باشه که حلقه در سمت Client ایجاد بشه و در خلال این حلقه، شما SP مورد نظر رو با پارامترهای دلخواه Call کنین. با این روش Client میتونه Progress Bar رو به پیش ببره!

Babak-Aghili
جمعه 16 تیر 1385, 14:48 عصر
مرسی امین جان ... کلی داشتم ناامید میشدم ...بدون امین هرگز !

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

http://www.barnamenevis.org/forum/showpost.php?p=248907&postcount=1


ضمنا مساله را با اجنبی ها هم مطرح کردم ... ! آخرین کسی که جواب داده هم بد نیست نگاهی به جوابش بندازیم ... شما بهتر زبون اینها را میفهمید !!
http://www.sqlservercentral.com/forums/shwmessage.aspx?forumid=8&messageid=292307

AminSobati
جمعه 16 تیر 1385, 17:16 عصر
بسیار خوب، حالا دقیق تر متوجه نیازت شدم!
راه حلی که در آخرین پست توسط دوست اجنبیمون پیشنهاد شده بود اینه که شما یک جدول داشته باشی که وقتی ساخت کرسر انجام میشه، یک ID یونیک (مثلا GUID) به این کار اختصاص بدی و ID رو به کلاینت معرفی کنی. بعد وقتی کرسر شروع به انجام کارش میکنه، در اون جدولی که صحبتش رو کردیم، شماره رکورد فعلی رو برای اون ID بخصوص Update کنیم به شکلی که با مراجعه به این ID در جدول، بدونیم الان چندمین رکورد در حال پردازشه. حالا کلاینت یک Thread جدید باید بسازه و هر چند ثانیه یکبار با داشتن ID، از جدول بخونه که رکورد چندم در حال پردازشه و به مقدار کافی Progress Bar رو حرکت بده. علت نیاز به ایجاد Thread جدید اینه که وقتی شما از کلاینت یک SP رو صدا میزنید که کرسر بسازه و بقیه کارها رو انجام بده، فرم شما Freeze میشه و نمیتونین کار دیگه ای انجام بدین. اما داشتن یک Thread دیگه این مشکل رو باید برطرف کنه. از این لحاظ امکانات جدیدی در ADO.NET 2 وجود داره به این صورت که وقتی دستوری رو به SQL Server ارسال میکنید، فرم Freeze نشه! یعنی خودش Thread رو ایجاد میکنه.
اما روش پیشنهاد شده چند اشکال داره:
- عمل Update به تعداد زیاد روی جدول حاوی ID باید در خلال کرسر انجام بشه
- ساخت Thread جدید و تغییر Progress Bar که در Thread دیگری هست نمیدونم تا چه حد میتونه مستعد Bug باشه
- Thread جدید باید هر چند ثانیه اون جدول رو Query کنه؛ یعنی ایجاد یک Connection جدید و رفت و برگشتهای بیشتر

یک روش دیگه من پیشنهاد میکنم:
کاربر نیازی نداره که به ازای هر رکوردی که پردازش میشه، تغییری در Prog Bar ببینه. بلکه هر چند ثانیه یکبار هم که Prog Bar حرکت کنه، خیالش راحت میشه که برنامه شما داره کارش رو انجام میده. لذا میتونیم کار پردازش رکوردها رو به چند Unit کوچکتر تقسیم کنیم. مثلا با پردازش هر 100 رکورد، Prog Bar یک حرکتی نشون بده! لذا در روش قبل شما میتونین با پردازش هر 100 رکورد، اون جدول رو Update کنین و در فواصل زمانی طولانی تر کلاینت جدول رو Query کنه. و یا این روش رو استفاده کنید که همیشه در SELECTی که برای ساخت کرسر استفاده میکنید، TOP 100 رو قرار بدین تا وقتی این 100 رکورد پردازش شد و اجرای برنامه به کلاینت برگشت، شما Prog Bar رو حرکت بدین و چون میدونین تا کدوم رکورد الان پردازش جلو رفته، موقع ساخت مجدد کرسر، توسط WHERE ID>x رو داخل Query قرار میدین که x در حقیقت ID آخرین رکورد پردازش شده بوده و مجددا TOP 100 میگیرید و الی آخر...
اشکالات این روش:
- هنوز تعداد رفت و برگشتها بین کلاینت و سرور بیش از یکبار هستش
- شما تعداد دفعات بیشتری Query انجام میدین

من روش بهتری به ذهنم نمیرسه بابک جان (بعید هم میدونم وجود داشته باشه). اما یادت نره که ساخت کرسر از 1000 رکورد یا بیشتر، کار جالبی نیست! مگر اینکه ناچار باشی...

titbasoft
جمعه 27 مرداد 1385, 20:30 عصر
با رخصت از بوجود آورنده تاپیک و ضمن یاد آوری یک تاپیک دیگه: http://www.barnamenevis.org/forum/showthread.php?t=21008
و اینکه فکر کنم این سوال رو حظوری هم از جناب ثباتی پرسیدم اما اگر دوباره راهنمایی کنید ممنون میشم:
آیا servise broker برای این مساله هیچ کمکی نمی کنه؟ نمی دونم چرا ولی یه مقدار احساس می کنم کلاینت با سرور دوست تر شده اند ، شاید بشه یک روش های سرخ پوستی استفاده کرد.

AminSobati
دوشنبه 30 مرداد 1385, 22:41 عصر
SSB کمک خوبی به ارتباط بین Client و Server میکنه اما سرعت Loop معمولا بسیار بالاتر از اینه که Messageها از Server به Client برن و Event رو فعال کنند. یعنی SSB از Loop عقب می افته!