Q. Which of the following are true about cursors? (Choose 2)
1) the default behavior for cursors is scrollable
2) scrollable cursors are always read only
3) scrollable cursors may only update one table at a time
4) the default behavior for cursors is non-scrollable
5) only one scrollable cursor can be used on a server at a time
A : 2), 4)
※ default cursor : semi-sensitive, non-scrollable
(아무 function 없이 declare 만 했을 경우 가지는 default 속성)
※ All scrollable cursors are read-only.
(모든 scrollable cursors는 read-only 속성을 갖음)
※ Any cursor that can be updated is non-scrollable.
(for update mode으로 선언된 cursor는 모두 non-scrollable 속성을 갖음)
※ Cursor
select 문으로 긁은 data를 담은 것으로 두 개의 부분(part)으로 이루어져 있다.
1. Cursor result set : select문으로 긁은 data set (table)
2. Cursor position : 위의 결과 set 의 한 row에 대한 포인터
( a pointer to a row within the cursor result set )
Cursor의 동작(cursor’s behavior)에 따른 두 가지 속성
1. sensitivity : base table 의 data변경에 영향을 받는지 안 받는지의 여부
1.1. insensitive
- cursor가 open된 이후에 base table(cursor를 선언했을 때 select문에 사용되어진 table)의
data가 변경되더라도 cursor의 result set에는 영향이 없다.
1.2. semi-sensitive (default)
- cursor가 open된 이후에 base table의 data가 변경되면 cursor result set에 반영이 될 수도
있고 안 될 수도 있다. (참... 무책임하다..ㅡ.,ㅡ)
( If you declare it semi_sensitive, some changes in the base tables
made since opening the cursor may appear in the result set. Data changes
may or may not be visible to the semi-sensitive cursor. )
2. scrollability : 순차적으로 fetch를 할 수 있느냐 없느냐의 여부
2.1. scroll
- ASE 15.0 부터 지원되는 기능
- 모든 scrollable cursors는 read-only 속성을 갖음
- 기존 버전에서는 fetch가 순차적으로만, 또 한번 fetch된 row는 재 fetch를 못했던 것과 달리
순차적 뿐 만 아니라. 자신이 원하는 행의 row를 바로 fetch할 수 있고 한 번 fetch된 rows를
반복해서 fetch할 수도 있음. 또한, 역순서로도 fetch할 수 있는 기능 제공 함.
- 동시에 한 row 이상 fetch된 cursor result set 을 검색, 이동할 수 있다.
( “Scrollable” means that you can scroll through the cursor result set by fetching
any, or many, rows, rather than one row at a time; you can also scan the result
set repeatedly.
A scrollable cursor allows you to set the position of the cursor
anywhere in the cursor result set for as long as the cursor is open, by specifying
the option first, last, absolute, next, prior, or relative in a fetch statement. )
ex)
fetch last [from] <cursor_name>
fetch absolute 500 [from] <cursor_name>
2.2. no scroll (default)
- 기존 버전과 다를 바 없음. 순차적으로만 fetch 가능.
- for update mode으로 선언된 cursor는 모두 non-scrollable.
※ read-only mode으로 선언된 cursor는 where절에 쓸 수 없지만,
update mode으로 선언된 cursor는 where절에 쓸 수 있다.
[read-only mode 의 Example]
-- 1. cursor 선언
declare types_insert cursor
for select distinct type from titles
for read only
go
declare @type char(12),
@avg_price money
-- 2. cursor open
open types_insert
-- 3. fetch
fetch types_insert into @type
while @@sqlstatus = 0
begin
select @avg_price = avg(price) from titles where type = @type
insert into types values (@type, @avg_price)
fetch types_insert into @type
end
-- 4. cursor close (close된 cursor는 deallocate되지 않는 한 재 open 할 수 있음.)
close types_insert
-- 5. cursor deallocate (메모리로부터 완전 제거, 재 open 할 수 없음.)
deallocate cursor types_insert
select * from types
go
[update mode 의 Example]
--> Declare cursor.
--> Declare variables.
--> Open cursor.
declare price_update cursor
for select title, price, total_sales from titles
for update
go
declare @avg_sales int,
@avg_price money,
@title varchar(80),
@price money,
@total_sales int
open price_update
begin tran
select @avg_sales = avg(total_sales),
@avg_price = avg(price)
from titles holdlock
--> Fetch the first row into the target list.
fetch price_update into @title, @price, @total_sales
--> Start a while loop that executes if there are more rows to fetch.
begin /* of while loop */
--> Check for a fetch error. If one occurred,
-- roll back the transaction, send an error
-- message to the user, close and deallocate
-- the cursor and exit the batch.
while @@sqlstatus <> 2
if @total_sales > @avg_sales and @price < @avg_price
begin
--> Increase the price in the titles table by 10%.
update titles
set price = price * $1.10
where current of price_update
if @@error <> 0
begin
rollback tran
raiserror 22001 "Update failed"
--> Close and deallocate cursor.
close price_update
deallocate cursor price_update
end
else
print "Increased price of %1! by 10 percent.", @title
end
else if @total_sales < @avg_sales and @price > @avg_price
begin
update titles
set price = price * $0.80
where current of price_update
if @@error <> 0
begin
rollback tran
raiserror 22001 "Update failed"
--> Close and deallocate cursor.
close price_update
deallocate cursor price_update
end
else
print "Decreased price of %1! by 20 percent.", @title
end
fetch price_update into @title, @price, @total_sales
end /* end of while loop */
if @@sqlstatus = 1
begin
rollback tran
raiserror 21001 "Fetch failed in cursor."
close price_update
deallocate cursor price_update
return
end
commit tran
--> Close and deallocate cursor.
close price_update
deallocate cursor price_update
go
'ASE Certification 준비' 카테고리의 다른 글
| Scrollable Cursor (0) | 2009/07/08 |
|---|---|
| partition에 관한 문제 (0) | 2009/07/01 |
| grant 에 관한 문제 (0) | 2009/07/01 |


