دوستان این تایپیک بخشی از مقاله آقای ASKaffash هست که در اون Cursor ها رو به خوبی توضیح داده. با توجه به منابع فارسی کم من تصمیم گرفتم این بخش از این مقاله خوب رو اینجا قرار بدم تا دوستان دسترسی مستقیم تری به این بخش از آموزش داشته باشند.

Cursor :
هنگام استفاده از دستورات SQL نظیر Select کلیه رکوردهای درخواستی بطور کامل استخراج می گردد اما در مواردی نیاز است که رکوردهای استخراج شده تحت شرایطی خاص مورد پردازش مجدد قرار گرفته و به برنامه درخواست کننده ارسال گردد در این صورت استفاده از کرسرها بسیار حائز اهمیت خواهد بود در واقع برای استفاده از یک کرسر می توان به ترتیب مراحل ذیل عمل نمود.
- یک متغیر از نوع کرسر تعریف می گردد. که شامل دستور Select درخواستی خواهد بود.
- با استفاده از دستور Open یک کرسر آماده استفاده می گردد.
- با استفاده از دستور Fetch حرکت درون یک کرسر امکان پذیر می گردد که در این حالت مقدار فیلدهای اعلام شده در رکورد جاری در دسترس می باشد.
- با استفاده از دستور Close کرسر فعال شده بسته می شود.
- با استفاده از Deallcate فضای اختصاص داده شده برای کرسر آزاد می گردد.

روش ایجاد کرسر :
شکلی از دستور Declare قادر به ایجاد نوع داده ای تحت عنوان کرسر خواهد بود که در شکل کلی ذیل قابل ارائه می باشد:

Global ] یا Cursor [ Local نام کرسر Declare
] Dynamic یا Keyset یا Scroll ] [ Static یا [ Forward_Only
Optimistic ]یا Scroll_Locks یا[ Read_Only
دستور For Select
] ] ستون ها [ For UpDate [ Of


براساس این دستور موارد ذیل می بایستی مدنظر قرار گیرد:
- Local که پیش فرض دستور است باعث ایجاد یک کرسر محلی در یک SP یا Trigger خواهد بود که با خروج از آنها بطور اتوماتیک حافظه مربوطه آزاد خواهد شد.
- Global یک کرسر با زاویه دید عمومی ایجاد می کند که در کلیه SP ها یا دستورات اجرائی در دسترس خواهد بود و درصورت پایان ارتباط بصورت اتوماتیک حافظه مربوطه آزاد خواهد شد.
( 67 )

- Forward_Only که پیش فرض دستور است یک کرسر رو به جلو ایجاد می کند که در این حالت حرکت اشاره گر رکورد به عقب مجاز نخواهد بود و این موضوع سرعت عملیات را نیز افزایش می دهد و در مقابل Scroll قابلیت جلو و عقب را برای کرسر ممکن می سازد.
- Static که پیش فرض دستور می باشد کرسری است که یک کپی موقت درون پایگاه داده TempDB ایجاد می کند و در این حالت هیچ عکس العملی را به داده های اصلی منعکس نمی کند.
- Keyset کرسری ایجاد می کند که تغییرات ایجاد شده توسط دیگران به شما منعکس می گردد و حذف و افزودن رکورد توسط دیگران به این کرسر منعکس نخواهد شد.
- Dynamic یک کرسر متغیر ایجاد می کند که کلیه تغییرات توسط دیگران به کرسر منعکس می گردد.
- Read_Only کرسری ایجاد می کند که تغییرات در داده ها را منعکس نخواهد کرد.
- Scroll_Locks نوعی کرسر ایجاد می کند که تضمین می نماید که سطرها را به همان طریقی که خوانده است جهت تغییرات بعدی قفل نماید.
- Optimistic نوعی کرسری است که تغییرات در داده ها را تضمین نمی کند و اطلاعات قفل نمی شود و جهت اعمال تغییرات در صورت وجود فیلد از نوع TimeStamp استفاده کرده و در غیراینصورت از مقدار CheckSum رکورد استفاده می نماید.
- دستور Select اعلام شده همان فرمان استاندارد Select می باشد و استفاده از فرامینی مشابه Into درون یک کرسر مجاز نخواهد بود.
- پارامتر اختیاری For UpDate جهت تعیین ستونهای قابل ویرایش پیش بینی شده است.

حرکت روی رکوردها ( Fetching ) :
مشابه همه ابزارهای ارتباط با پایگاه داده نظیر ADO حرکت روی رکوردهای بازگشتی با استفاده از دستور Fetch امکان پذیر است و شکل کلی دستور Fetch به صورت ذیل می باشد:

یا Last یا First یا Prior یا Fetch [ Next
] مقدار نمو Relative یا شماره رکورد Absolute
نام کرسر یا متغیر از نوع کرسر From
] فهرست متغیرها [ Into

( 68 )

پارامترهای بکار رفته در دستور به شکل ذیل خواهد بود:
- Next که پیش فرض دستور است حرکت به رکورد بعدی را میسر می کند.
- Prior حرکت اشاره گر به رکورد قبلی خواهد بود.
- First حرکت اشاره گر به رکورد اولیه خواهد بود.
- Last حرکت اشاره گر به رکورد انتهائی خواهد بود.
- Absolute اشاره گر را به شماره رکورد اعلام شده هدایت می کند.
- Relative اشاره گر را به اندازه تغییرات اعلام شده نسبت به رکورد جاری هدایت می کند.
- درصورتیکه قرار است ستونهای رکورد جاری در تعدادی متغیر جانشین شود از فرمان Into به همراه فهرست متغیرها که قبلاً اعلام شده اند استفاده می گردد.
- مقدار تابع @@Fetch_Status وضعیت کنونی کرسر را مورد تحلیل قرار می دهد و درصورتیکه مقدار صفر را داشته باشد نشان می دهد که عملیات دریافت داده توسط کرسر موفقیت آمیز بوده است.

مثال) در سیستم پرسنلی تابعی بنویسید که متوسط تحصیلات افراد تحت تکفل هر شخص را محاسبه کند.
همانطور که از ظاهر درخواست معین است جدول ChdLvL جهت انجام عملیات Fetch مناسب ترین انتخاب است بدین منظور می نویسیم:
Create Function AvgLvL (@PrsID Int )
Returns Real
AS Begin
Declare @i TinyInt , @L Real , @A Real
Set @i = 0 Set @A = 0
Declare TmPCursor Cursor For
Select LID From ChdLvL Where PrsID = @PrsID
Open TmPCursor
While 1=1 Begin
Fetch Next From TmPCursor Into @L
If @@ Fetch_Status < > 0 Break
Set @i = @i + 1
Set @A= @A +@L
End
Close TmPCursor
Deallocate TmPCursor
If @i < >0 Set @A = @A / @i
Return @A
END
( 69 )
در برنامه طراحی شده شماره کارمندی بعنوان پارامتر ورودی به تابع AvgLvL وارد می گردد و در خط ششم کرسری بنام TmPCursor براساس دستور Select که افراد تحت تکفل PrsID خاصی را باز می گرداند ایجاد شده است و درون حلقه مقدار کلیه تحصیلات افراد تکفل جمع می شود و براساس @@Fetch_Status انتهای کرسر کنترل می گردد ، سپس کرسر ایجاد شده بادستور Close بسته می شود و دستور Deallocate حافظه ایجاد شده توسط کرسر را آزاد می کند و در انتهای برنامه تابع میانگین سطح تحصیلات را باز می گرداند ، شایان ذکر است که میانگین سطح تحصیلات افراد تحت تکفل با استفاده از یک Select نیز قابل محاسبه بود ولی در این تابع تنها هدف استفاده از کرسرها می باشد چون در مواردی با استفاده از یک دستور Select نمی توان درخواست موردنظر را محقق کرد ، بعنوان مثال در مواردیکه نتیجه ای وابسته به مقایسه هر رکورد با رکورد ماقبل یا مابعد باشد استفاده از کرسرها یک الزام خواهد بود.