
تا حالا شده بخوای تو SQL Server دادههاتو ردیفبهردیف بررسی کنی؟ مثلاً بری سراغ هر مشتری، ببینی چقدر خرید کرده، یه شرطی بزاری، یه پیامی براش بسازی یا حتی رکوردش رو آپدیت کنی؟ خب، اینجا جاییه که پای CURSOR وسط میاد.
حالا CURSOR چیه؟ یه جور حلقهست! یعنی میتونی باهاش رکوردها رو یکییکی بخونی، کاری روشون انجام بدی، بعد بری سراغ بعدی. اما صبر کن! قبل از اینکه عاشقش بشی، باید بدونی که CURSOR یه شمشیر دولبهست!
این CURSOR چطوری کار میکنه؟
به زبان خیلی ساده:
اول تعریفش میکنی (میگی چه دادههایی رو میخوای بخونی)،
بازش میکنی،
شروع میکنی رکوردها رو یکییکی گرفتن،
کارتو انجام میدی،
آخرشم که درش میاری! (ببندش و منابعشو آزاد کن)،
یه مثال سریع:
فرض کن یه جدول به اسم Employees داریم:
//
DECLARE @Name NVARCHAR(100)
DECLARE EmployeeCursor CURSOR FOR
SELECT FullName FROM Employees
OPEN EmployeeCursor
FETCH NEXT FROM EmployeeCursor INTO @Name
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'کارمند: ' + @Name
FETCH NEXT FROM EmployeeCursor INTO @Name
END
CLOSE EmployeeCursor
DEALLOCATE EmployeeCursor
//
همینقدر راحت. یکییکی میره سراغ اسم کارمندا و اسمشون رو چاپ میکنه.
مشکل اینجاست که CURSOR تو حجم بالای دادهها کند عمل میکنه. چون برخلاف دستورات Set-Based (که کل جدول رو یه جا پردازش میکنن)، CURSOR رکورد به رکورد جلو میره.
یه جورایی مثل اینه که بهجای استفاده از ماشین لباسشویی، بشینی لباسا رو دونهدونه با دست بشوری!
✅ وقتی که واقعاً نیاز داری دادهها رو دونهدونه بررسی کنی. مثلاً:
❌ ولی اگه میتونی با یه UPDATE یا SELECT ساده کارت راه بیفته، CURSOR فقط سرعت کارت رو کم میکنه.
حالا بریم چندتا ترفند برای استفاده بهتر از CURSOR
اگه مجبور شدی استفاده کنی، حداقل:
FAST_FORWARD یا READ_ONLY استفاده کن تا سریعتر باشهCLOSE و DEALLOCATE کن تا منابع آزاد بشنمثلاً اینجوری سریعتر میشه:
DECLARE MyCursor CURSOR FAST_FORWARD FOR
SELECT ProductName FROM Products
در CURSOR همونقدر که میتونه مفید باشه، اگه بیجا استفاده بشه میتونه قاتل پرفورمنس باشه.
قبل از اینکه سمتش بری، از خودت بپرس:
"آیا واقعاً راه دیگهای نیست؟!
اگه جواب منفی بود، با خیال راحت ازش استفاده کن… ولی هوشمندانه!