فصل بیست و نهم :
Cursor
کرسر در واقع ابجکتی است که بروی دیتا بصورت رکورد به رکورد کار میکند.ممکن است در انجام محاسباتی به روشی نیاز داشته باشیم که رکورد هایی را یکی یکی برسسی و یا بروز رسانی کنیم و نه bulk . در اینصورت کرسر ها می توانند به ما کمک کنند.
DECLARE cursor_name CURSOR [ LOCAL | GLOBAL ]
[ FORWARD_ONLY | SCROLL ]
[ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
[ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]
[ TYPE_WARNING ]
FOR select_statement
[ FOR UPDATE [ OF column_name [ ,...n ] ] ]
[;]
While
در این دستور شرطی را تعیین می کنیم که تا زمانی آن شرط درست باشد یک بلاک از دستورات tsql بصورت مکرر (حلقه)اجرا شوند. تا زمانی که رط ما درست باشد بلاک دستورات تا ابد تکرار خواهند شد.
WHILE Boolean_expression
{ sql_statement | statement_block | BREAK | CONTINUE }
DECLARE @intFlag INT
SET @intFlag = 1
WHILE (@intFlag <=5)
BEGIN
PRINT @intFlag
SET @intFlag = @intFlag + 1
END
@@FETCH_STATUS
وضعیت اخرین fetch انجام شده را باز می گرداند
صفر یعنی fetch موفقیت امیز بوده . برای شرط حلقه چک میکنیم که مقدار این تابع 0 باشد. مقادیر منفی نشان دهنده وجود مشکل و یا نبودن رکوردی دیگر در مجموعه نتایج است
Open : سلکت ما را اجرا میکند و نتایج را بر میگرداند. Fetch یک رکورد را ار نتایج سلکت ما باز میگرداند و در متغیر های ما قرار میددهد.
مثلا کرسری بنویسید که نام و نام خانوادگی تمام دانش اموزان را نمایش دهد .
declare @FirstName nvarchar(100);
declare @LastName nvarchar(100);
declare @Total nvarchar(1000)
declare cur1 cursor
for select FirstName,LastName from Student
open cur1
fetch next from cur1
into @FirstName,@LastName;
while @@FETCH_STATUS=0
begin
--set @Total =@Total + @FirstName+@LastName + space(5)
set @Total =concat(@Total ,@FirstName,@LastName , space(5))
--select @FirstName,@LastName;
fetch next from cur1
into @FirstName,@LastName;
end
close cur1;
deallocate cur1
select @Total
مثلا کرسری بنویسید که مبلغ salary هر کاربر را اگر اسمش شامل محمد بود 100 دلار اضافه کند و اگر اسمش شامل
علی بود 50 دلار اضافه کند .
declare @FirstName nvarchar(100);
declare @ID smallint
declare cur1 cursor
for select FirstName,ID from Student
open cur1
fetch next from cur1
into @FirstName,@ID;
while @@FETCH_STATUS=0
begin
--set @Total =@Total + @FirstName+@LastName + space(5)
if @FirstName like N'محمد'
update Student set Salary =Salary+100 where id=@ID
else if @FirstName like N'علی'
update Student set Salary =Salary+50 where id=@ID
--select @FirstName,@LastName;
fetch next from cur1
into @FirstName,@ID;
end
close cur1;
deallocate cur1
نکته مهم این است که چون کرسر ها رکورد به رکورد روی دیتا کارمیکنند سرعتشان به مراتب کمتر است از موقعی که مثلا یک آپدیت بنویسیم که یکباره بروی دیتا اعمال شود . لذا اولویت در نوشتن کوئری هایی است که بدون کزسر بتوانند نیاز ما را بر آورده سازند .
کرسر ها کند ترین روش کار بروی اطلاعات هستند. لذاتا مجبور نشدید از آنها استفاده نکنید. در مواردی دیده شده که یک کرسر حتی تا 20 بار کند تر از معادل آن می باشد.
نکته » اگر در کرسری آپدیت بروی اطلاعات جدول base انجام نمی دهیم می توانیم با آوردن عبارت read only عملکرد کرسر را بطور چشمگیری بهبود ببخشیم
بسیاری از مفاهیم درفیلم اموزشی بطور مفصل شرح داده شده اند . لذا حتما فیلم آموزشی این فصل را ببینید .
مفاهیم و موضوعات این فصل عبارتند از :