반응형

Cursors
Cursors는 sql select문의 결과의 집합에 대한 포인터이다.
이것은 한번에 하나씩 여러 개의 행들을 검색하거나 작업할 수 있도록 한다. 커서는 가상변수로 생각할 수 있으며, 특수한 명령들을 이용하여 그 변수를 사용한다.
. DECLARE - 그 커서의 SELECT 문을 명시한다.
. OPEN - 그 커서의 SELECT 문을 수행한다.
. FETCH - 그 커서의 한 행을 읽는다.
. UPDATE WHERE CURRENT OF cursor - 그 읽어진 행을 수정한다.
. DELETE WHERE CURRENT OF cursor - 그 읽어진 행을 삭제한다.
. CLOSE - 커서 작업을 종료한다.


1.DECLARE
모든 변수를 선언하듯이 커서도 사용하기 전에 반드시 선언하여야 한다. 커서의 선언은 반드시 하나의 SQL SELECT 문을 포함하여야 한다. DELCLARE는 변수선언과 같이 수행문이 아니다. 그러므로 DECLARE는 그 트랜잭션객체의 SqlCode와 SqlErrText와 같은 오류 속성들의 값을 지정하지 않는다.
DECLATE cursor1 CURSOR FOR
SELECT  payment, deposit
FROM    checkbook
ORDER BY checkdate, checkno;

2. OPEN
커서을 선언하고 나면 그 커서를 사용하기전에 반드시 오픈하여야 한다. OPEN은 그 커서의 선언문에서 명시된 SQL SELECT 문을 수행한다. SELECT 문의 수행이 실패할 수도 있으므로 다른 수행가능한 삽입된 SQL 문과 같이 OPEN을 수행한 다음에 SqlCode을 검사하여야 한다.
OPEN cussor1;
IF sqlca.SqlCode <> 0 then.......

3. FETCH
성공적으로 커서을 오픈하면 FETCH는 하나의 행을 변수로 읽어온다. OPEN은 그 커서의 위치를 첫 번째 행의 바로전에 위치시킨다. FETCH는 묵시적으로 그 다음의 행을 읽어온다. 전형적으로 FETCH문을 루프 안에 넣고 "notfound" 오류가 발생할 때까지 반복적으로 수행한다.
DO
   FETCHcusror1 INTO :decpayment, :decdeposit;
   IF sqlca.SqlCode =100 THEN EXIT         //더이상 남은 행이 없다.
   .......
   .......
   .......
LOOP while True

4. UPDTE와 DELETE
한행을 읽어 온 후, 그 커서가 가리키는 그 행을 수정하거나 삭제하기 위해 WHERE CURRENT OF cursor 절과 함께 UPDATE 또는 DELETE를 사용할수 있다.
UPDATE checkbook
   SET balance = :decbalance
WHERE CURRENT OF cursor1;
IF sqlca.SqlCode <> 0 then.......
물론, 단지 행을 읽기만을 원한다면 꼭 UPDATE 또는 DELETE를 사용해야 되는 의무는 없다.

5. CLOSE
커서의 작업이 끝나면 그것을 닫는다, 항상 그커서를 닫을 필요는 없다. COMMIT와 DISCONNECT가 자동적으로 그 커서를 닫아준다.

6. (예제1) : 커서를 사용하여 구조체의 행들을 읽어오기
첫째. 메뉴에서 Declare/Instance Variables를 선택 변수를 선언한다.
메뉴에서 Declare/Instance Variables를 선택하면 인스턴스 변수를 정의할수 있는 다이얼로그가 디스플레이 된다.
이곳에 단지 아래와 같은 선언문을 기술해주면된다.
DECLARE icur_store CURSOR FOR
SELECT storeid, storeaddress, storecity,
       storestate,storezip, salestaxrate
FROM store;
둘째.메뉴에서 Declate/Window Structures를 선택 구조체를 정의한다.
메뉴에서 Declare/Window Structures를 선택하면 구조체를 정의할수 있는 다이얼로그가 디스플레이 된다. 이곳에 구조체의 요소들인 변수명, 변수의 타입, 그리고 타입에 따라 자리수만을 계속해서 정의해주면 된다.
일단, ws_storerow란 이름의 구조체를 정의한것으로 가정하자
셋째. (예제2)스크립트에 커서문을기술한다.
....................................................................
Integer       li_rows      //FETCH된열을 계산할 변수
Ws_storerow   lstr_storerow
OPEN icur_store;
li_row = 0
DO
   FETCH isur_store INTO
   :lstr_storerow.s_storeid, :lstr_storerow.s_address,
   :lstr_storerow.s_city,    :lstr_storerow.s_state,
   :lstr_stoterow.s_zip,     :lstr_storerow.dec_salestaxrate;
   IF sqlca.SqlCode = 100 THEN EXIT      //더 이상의 열은 없다
      li_rows ++                         //하나 이상의 열을읽어 들였다.
      MessageBox ("store row #" +String(li_rows),             &
                  "Store id: -t"+lstr_storerow.s_storeid     +&
                  "-nAddresss: -t"+lstr_storerow.s_address   +&
                  "-nCity: -t-t"+lstr_storerow.s_city        +&
                  "-nState: -t-t"+lstr_storerow.s_ state     +&
                  "-nZip: -t-t"+ lstr_storerow.s_zip         +&
                  "-nSales Tax: -t"+lstr_storerow.s_salesstaxrate +&
LOOP WHILE True
CLOSE icur_store; // 커서을 닫는다.

 - 재스민의 파워빌더 싸부 수연아부지 DevTip에서 -

+ Recent posts