1. 컀μ
- Oracle μλ²μμ ν λΉν μ μ© λ©λͺ¨λ¦¬ μμμ λν ν¬μΈν°
- SQLλ¬Έμ μ²λ¦¬ν κ²°κ³Ό μ§ν©μ κ°λ¦¬ν€λ ν¬μΈν°
- μ§μ κ²°κ³Όλ‘ μ»μ΄μ§ μ¬λ¬ νμ΄ μ μ₯λ λ©λͺ¨λ¦¬ μμ μμΉ
- Oracle μλ² νλ‘μΈμ€ λ΄λΆμ Private SQL Area λΌλ λ©λͺ¨λ¦¬ μμμ κ²°κ³Ό μ§ν©μ΄ μ μ₯λ¨
- Private SQL Area : νΉμ 쿼리μ λν κ²°κ³Όλ₯Ό μ μ₯νκ³ μΊμ±νλ μν
- ν μΈμ
μμμ κ°μ 쿼리λ₯Ό λ°λ³΅ νΈμΆνλ©΄ μ μ₯λμ΄ μλ κ²°κ³Ό μ§ν©μ λ°ν > μμ λλΉ μ΅μν
- SELECTλ¬Έμ κ²°κ³Ό μ§ν©μ μ²λ¦¬νλλ° μ¬μ©
1-1. μμμ 컀μ(Implict Cursor)
- λ΄λΆμμ μλμΌλ‘ μμ±λμ΄ μ¬μ©
- Oracle DBμμ μ€νλλ λͺ¨λ SQLλ¬Έμ₯μ μμμ 컀μκ° μμ±λλ©°, 컀μ μμ±μ μ¬μ© κ°λ₯
- Oracle μλ²μμ SQLλ¬Έμ μ²λ¦¬νκΈ° μν΄ λ΄λΆμ μΌλ‘ μμ± λ° κ΄λ¦¬ν¨
- λͺ¨λ DMLκ³Ό PL/SQL SELECTλ¬Έμ λν΄ μ μΈλ¨
- PL/SQL λΈλ‘ μμμ μ€ννλ SQL λ¬Έμ₯ μ€ν μ μλμΌλ‘ λ§λ€μ΄μ Έ μμ±
- SQLλ¬Έμ΄ μ€νλλ μκ° μλμΌλ‘ OPEN, CLOSEλ₯Ό μ€ν
- SQL 컀μ μμ±μ μ¬μ©νλ©΄ SQLλ¬Έμ κ²°κ³Όλ₯Ό ν
μ€νΈν μ μμ
1-1-1. μμμ 컀μ μμ±
SQL%FOUND
: ν΄λΉ SQLλ¬Έμ μν΄ λ°νλ νμκ° 1κ° μ΄μμ΄λ©΄ TRUE
SQL%NOTFOUND
: ν΄λΉ SQLλ¬Έμ μν΄ λ°νλ νμκ° μμΌλ©΄ TRUE
SQL%ISOPEN
: μμμ 컀μκ° μ΄λ €μλμ§ μ¬λΆ νμΈ, νμ FALSE (PL/SQLμ μ€ν ν λ°λ‘ 묡μμ 컀μλ₯Ό λ«κΈ° λλ¬Έ)
SQL%ROWCOUNT
: ν΄λΉ SQLλ¬Έμ μν΄ λ°νλ μ΄ νμ, κ°μ₯ μ΅κ·Ό μνλ SQLλ¬Έμ μν΄ μν₯ λ°μ νμ
1-1-2. μμμ 컀μ μμ
DECLARE
v_user_num NUMBER := 8;
v_cnt NUMBER;
BEGIN
DELETE FROM USER_INFO WHERE USER_NUM > v_user_num;
dbms_output.put_line('DELETE 건μ : ' || SQL%ROWCOUNT);
IF SQL%FOUND THEN dbms_output.put_line('ν¨μΉ λ‘μ° μ 1κ° μ΄μ');
ELSE dbms_output.put_line('ν¨μΉ λ‘μ° μ 0κ°');
END IF;
IF SQL%ISOPEN THEN dbms_output.put_line('컀μ μ΄λ¦Ό');
ELSE dbms_output.put_line('컀μ λ«ν');
END IF;
END;
/
/* κ²°κ³Ό
DELETE 건μ : 1
ν¨μΉ λ‘μ° μ 1κ° μ΄μ
컀μ λ«ν */
1-2. λͺ
μμ 컀μ(Explict Cursor)
- μ¬μ©μκ° μ§μ μ μν΄μ μ¬μ©νλ 컀μ
- κ²°κ³Ό λ°μ΄ν° μ§ν©μ ROW λ³λ‘ μ°Έμ‘°ν΄ μμ
ν΄μΌ ν λ μ μ©ν¨
- PL/SQLμμ SELECTλ¬Έ μ¬μ© μ INTOλ₯Ό ν¨κ» μ¬μ©ν΄μΌ νλ©°, νμ λ¨μΌνλ§ λ¦¬ν΄ λ°μμΌ ν¨
- 컀μ μ¬μ© μ SQL μ²λ¦¬ κ²°κ³Ό μ§ν©μ κ°μ Έμ 볡μνμ λν μμ
λ κ°λ₯
1-2-1. λͺ
μμ 컀μ μμ±
%FOUND
: FETCHν λ°μ΄ν°κ° νμ λ°ννλ©΄ TRUE
%NOTFOUND
: FETCHν λ°μ΄ν°κ° νμ λ°ννμ§ μμΌλ©΄ TRUE (LOOP μ’
λ£ν μμ μ μ°Ύμ)
%ISOPEN
: 컀μκ° OPENλμ΄ μμΌλ©΄ TRUE
%ROWCOUNT
: νμ¬κΉμ§ λ°νλ λͺ¨λ νμ μ
1-2-2. λͺ
μμ 컀μ λ¬Έλ²
- 컀μ μ΄κΈ°
OPEN
- κ²°κ³Ό ν μ§ν©μ μλ³
- 컀μ μμ κ²μμ΄ μ€νλλ©° μλ¬΄λ° λ°μ΄ν° νμ μΆμΆνμ§ λͺ»ν΄λ μλ¬κ° λ°μνμ§ μμ
- 컀μ ν¨μΉ
FETCH
- νμ¬ νμ λ³μμ λ‘λ(νμ¬ νμ΄ μμ λκΉμ§ μνν μ μμ)
- νμ¬ λ°μ΄ν° νμ OUTPUT λ³μμ λ°ν
- 컀μμ SELECTλ¬Έμ 컬λΌκ³Ό OUTPUT λ³μμ νμ
, κ°μκ° λμΌν΄μΌ ν¨
- 컀μλ ν λΌμΈμ© λ°μ΄ν°λ₯Ό FETCHν¨
- λ¬Έλ² :
FETCH cursor_name INTO variable1, variable2;
- 컀μ λ«κΈ°
CLOSE
- κ²°κ³Ό ν μ§ν©μ ν΄μ
- μ¬μ©μ λ§μΉ 컀μλ λ°λμ λ«μμ£Όμ΄μΌ ν¨
- νμ μ 컀μλ₯Ό λ€μ μ΄ μ μμ
- 컀μλ₯Ό λ«μ μνμμ FETCH λΆκ°λ₯
- λ¬Έλ² :
CLOSE cursor_name;
DECLARE
- λͺ
λͺ
λ SQL μμμ μμ±
DECLARE
CURSOR [컀μλͺ
] IS [SELECT ꡬ문];
BEGIN
OPEN [컀μλͺ
];
FETCH [컀μλͺ
] INTO [λ‘컬λ³μ];
CLOSE [컀μλͺ
];
END;
/
1-2-3. λͺ
μμ 컀μ μμ
DECLARE
v_num NUMBER := 5;
CURSOR userCursor -- 컀μ μ μ
IS
SELECT * FROM USER_INFO
WHERE USER_NUM < v_num;
userData USER_INFO%ROWTYPE; -- λ³μ μ μ
BEGIN
OPEN userCursor;
LOOP
FETCH userCursor INTO userData; -- νλμ© λ³μμ λ£κΈ°
EXIT WHEN userCursor%NOTFOUND; -- λμ΄μ μμΌλ©΄ EXIT
dbms_output.put_line(userData.USER_NUM || ' ' || userData.USER_NM);
END LOOP;
CLOSE userCursor;
END;
/
- μμ κ°μ΄ 컀μλ₯Ό μ μΈνμ¬ μ¬μ©νλ λ°©λ², μλμ κ°μ΄ CURSOR FOR LOOPλ₯Ό μ¬μ©νλ λ°©λ²μ΄ μμ
- μλΈ μΏΌλ¦¬λ₯Ό νμ©νμ¬
CURSOR FOR LOOP
μ¬μ© > CURSORλ₯Ό μ μΈνμ§ μμλ λ¨
FOR LOOP
κ° μλμΌλ‘ 컀μλ₯Ό OPEN, CLOSE ν΄μ€
- νμ΄ μμ λκΉμ§ FETCH λν μλμΌλ‘ κ°λ₯
- ROWTYPEμ ν΄λΉνλ λ³μλ₯Ό λ°λ‘ DECLAREν νμκ° μμ (μμμ μΌλ‘ μ μΈλκΈ° λλ¬Έ)
-- forλ¬Έμ λ μ½λ μ μΈ(name_rec)
DECLARE
CURSOR name_list IS
SELECT USER_NM FROM USER_INFO;
BEGIN
FOR name_rec IN name_list
LOOP
dbms_output.put_line(name_rec.USER_NM);
END LOOP;
END;
/
-- λͺ
μμ 컀μ FOR LOOP
DECLARE
BEGIN
FOR name_list IN
( SELECT USER_NM FROM USER_INFO )
LOOP
dbms_output.put_line(name_list.USER_NM);
END LOOP;
END;
/
- CURSOR FOR LOOPμ λ΄λΆμ μΌλ‘ μ²λ¦¬λλ λ°μ΄ν°μ μ, I/O μΈ‘λ©΄μμ λ³΄λ€ ν¨μ¨μ μ΄λ―λ‘ κΆμ₯λ¨
1-3. 컀μ λ³μ
- λ³μμ νΉμ§μ΄ μλ 컀μ
- ν κ° μ΄μμ 쿼리λ₯Ό μ°κ²°ν΄ μ¬μ©ν μ μμ (μ¬μ¬μ©)
- 컀μ λ³μλ₯Ό ν¨μλ νλ‘μμ μ λ§€κ°λ³μλ‘ μ λ¬ κ°λ₯
- 컀μ μμ± μ¬μ© (v_cursor%FOUND, ...)
- 컀μλ λΈλ‘ μμμλ§ μ¬μ© κ°λ₯νλ©°, ν λ² μ μΈ ν λ³κ²½ λΆκ°
- λΈλ‘μ΄ μ¬λΌμ§ λ 컀μλ μ¬λΌμ§λ©°, λ€λ₯Έ λΈλ‘μμ μ¬μ© λΆκ°
- 컀μ λ³μλ‘ μ»€μ μ μΈνλ©΄, λ€λ₯Έ λΈλ‘μμλ μ¬μ© κ°λ₯νλ©° μ¬μ¬μ©μ΄ κ°λ₯ν΄μ§
1-3-1. 컀μ λ³μ μ μΈ
RETURN [λ°ν νμ
]
: λ°ννλ κ²°κ³Ό μ§ν© %ROWTYPE
- 컀μκ° λ°ννλ νμ
μ ν κ° μ΄μμ 컬λΌμ΄ μλ λ μ½λ νμ
- λ°ν νμ
μ΄ μμΌλ©΄ κ°ν 컀μ νμ
/ μλ΅νλ©΄ μ½ν 컀μ νμ
- SYS_REFCURSOR : μ€λΌν΄ λΉνΈμΈ 컀μ νμ
- λ³λλ‘ μ»€μ νμ
μ μΈν νμ μμ (μ½ν 컀μ νμ
)
TYPE [컀μ νμ
λͺ
] IS REF CURSOR [RETURN λ°ν νμ
];
[컀μ λ³μλͺ
] [컀μ νμ
λͺ
];
[컀μ νμ
λͺ
] SYS_REFCURSOR;
-- μμ
DECLARE
TYPE userCurType IS REF CURSOR RETURN USER_INFO%ROWTYPE;
testCursor SYS_REFCURSOR;
BEGIN
(μλ΅)
END
;
/
1-3-2. 컀μ λ³μ μ¬μ©
- CLOSEλ μ§μ ν νμκ° μμ
OPEN [컀μ λ³μλͺ
] FOR SELECT ~ ;
- 'USER_INFO' ν
μ΄λΈμ λ μ½λ νμ
μΌλ‘ 컀μλ₯Ό λ°μ 컬λΌμ λͺ¨λ λ μ½λμ λ΄κ³ , λ μ½λ νμ
λ³μλ‘ μμ μμ±μ μ κ·Όνμ¬ κ°μ μΆλ ₯
DECLARE
TYPE userCurType IS REF CURSOR RETURN USER_INFO%ROWTYPE;
userCur userCurType;
userData USER_INFO%ROWTYPE;
BEGIN
-- 컀μ μ΄κΈ°
OPEN userCur FOR SELECT * FROM USER_INFO WHERE USER_NUM < 5;
-- LOOP λ¬Έ
LOOP
FETCH userCur INTO userData;
dbms_output.put_line(userData.USER_NM || userData.USER_BIRTH);
EXIT WHEN userCur%NOTFOUND;
END LOOP;
END;
/
- λ€μκ³Ό κ°μ΄ μ½κ²°ν©μΌλ‘ κ°λ΅νκ² μ¬μ© κ°λ₯
-- λ°ν νμ
μλ΅
DECLARE
TYPE userCurType IS REF CURSOR;
userCur userCurType;
userData USER_INFO%ROWTYPE;
BEGIN
-- SYS_REFCURSOR
DECLARE
userCur SYS_REFCURSOR;
userData USER_INFO%ROWTYPE;
BEGIN
1-4. 컀μ ννμ
- SELECTλ¬Έμμ μ»¬λΌ ννλ‘ μ»€μλ₯Ό μ¬μ©νλ κ²
CURSOR(μλΈ μΏΌλ¦¬)
ννλ‘ μ¬μ©
- μλμ κ°μ΄ λ€μ€νμ 리ν΄νλ μλΈ μΏΌλ¦¬λ‘ μΈν΄ μ€λ₯ λ°μ μ, CURSORλ₯Ό μ΄μ©ν΄ λͺ¨λ νμ λν κ²°κ³Ό νμΈ κ°λ₯
SELECT
USER_NUM
, USER_NM
, (
SELECT STORE_NM FROM STORE_INFO WHERE OWNER_NUM = USER_NUM
) AS STORE_NM
FROM USER_INFO;
/* ORA-01427: λ¨μΌ ν νμ μ§μμ 2κ° μ΄μμ νμ΄ λ¦¬ν΄λμμ΅λλ€. */
SELECT
...
, CURSOR (
SELECT STORE_NM FROM STORE_INFO WHERE OWNER_NUM = USER_NUM
) AS STORE_NM
...
FROM USER_INFO;
/* κ²°κ³Ό
μκ°μ€ {<STORE_NM=κ΅λ³΄λ¬Έκ³ κ΄νλ¬Έμ >,}
μ‘κ° {}
λ‘μ΄ {<STORE_NM=μ μΈκ³ μλ±ν¬μ >,<STORE_NM=63λΉλ© μμΏ μ리μ>,} */
1-4-4. λ€μ€ν μΆλ ₯
- λ€μ€ν μλΈμΏΌλ¦¬λ₯Ό κ°λ¦¬ν€λ 컀μλ₯Ό λ³μμ λ΄μ κ°κ°μ νμΌλ‘ μΆλ ₯
- JAVAμ MAP 컬λ μ
κ³Ό μ μ¬ν νν
DECLARE
-- 컀μ μ μΈ
CURSOR user_cursor IS
SELECT
USER_NM
, CURSOR (SELECT STORE_NM FROM STORE_INFO WHERE OWNER_NUM = USER_NUM) AS STORE_NM
FROM USER_INFO;
-- νμ μ΄λ¦ λ³μ
v_user_name USER_INFO.USER_NM%TYPE;
-- μμ μ΄λ¦ μΆλ ₯μ μν 컀μ λ³μ
store_name_cursor SYS_REFCURSOR;
-- μμ μ΄λ¦ λ³μ
v_store_name STORE_INFO.STORE_NM%TYPE;
BEGIN
OPEN user_cursor;
LOOP
-- 컀μ μμ μ§ν©μ κ°μ Έμ΄
FETCH user_cursor INTO v_user_name, store_name_cursor;
EXIT WHEN user_cursor%NOTFOUND;
dbms_output.put_line('νμλͺ
: ' || v_user_name);
LOOP
FETCH store_name_cursor INTO v_store_name;
EXIT WHEN store_name_cursor%NOTFOUND;
dbms_output.put_line(' μμ λͺ
: ' || v_store_name);
END LOOP;
END LOOP;
END;
/
/* κ²°κ³Ό
νμλͺ
: μκ°μ€
μμ λͺ
: κ΅λ³΄λ¬Έκ³ κ΄νλ¬Έμ
νμλͺ
: μ‘κ°
νμλͺ
: λ‘μ΄
μμ λͺ
: μ μΈκ³ μλ±ν¬μ
μμ λͺ
: 63λΉλ© μμΏ μ리μ
*/