본문 바로가기

📚Study Note/ORACLE

[ ORACLE ] CURSOR 커서란,,,마츼 깜짝상자 같은 것💥🎁

--■■■■■■ 커서 (Cursor)  ■■■■■■■

--1. 오라클에서 하나의 레코드가 아닌 여러 레코드로 구성된 작업 영역에서
-- SQL 문을 실행하고 그 과정에서 발생한 정보를
-- 저장하기 위하여 커서를 사용하며
-- 커서에는 암시적 커서와 명시적 커서가 있다.

-- 2. 암시적 커서는 모든 SQL 문에 존재하며,
-- SQL 실행 후 오직 하나의 행(ROW)만 출력하게 된다.
-- 그러나 SQL 문을 실행한 결과문 (RESULT SET)이
-- 여러 행(ROW) 으로 구성된 경우
-- CURSOR(커서)를 명시적으로 선언해야 여러 행(ROW)을 다룰 수 있다.

 

솔직히 배웠는데도 이거 읽는데 모르겠다

 

 

-- ● 커서 이용 전 상황(단일 행 접근 시)
SET SERVEROUTPUT ON;

DECLARE
    V_NAME  TBL_INSA.NAME%TYPE;
    V_TEL   TBL_INSA.TEL%TYPE;
BEGIN     .
SELECT NAME, TEL INTO V_NAME,V_TEL
    FROM TBL_INSA
    WHERE NUM=1001;
    
    DBMS_OUTPUT.PUT_LINE(V_NAME || ' - ' || V_TEL);
       
END;

 

커서를 이용하기 전의 상황이다.

INSA 테이블의 특정한 사람의 (NUM이 1001) NAME 과 TEL을 선언한 변수에 넣고 출력했을 때 출력이 잘 된다.

하지만 문제가 되는 부분은 인사테이블에 있는 전체 인원의 이름과 전화번호를 출력하려고 할 때인데

그렇다고 WHERE 절을 빼버리면 출력이 되지 않는다. 

(이것은 앞선 예제를 통해 살펴봤기 때문에 가볍게 보고 넘어간다)

 

커서를 이용해서 단일 행이 아니라 다중 행에 접근하고자 한다.

 

DECLARE
    V_NAME TBL_INSA.NAME%TYPE;
    V_TEL TBL_INSA.TEL%TYPE;
    
    --커서 이용을 위한 커서변수 선언(→커서 정의)
    --커서는 데이터명 데이터타입 형태로 쓰는게아니라 CURSOR 커서명 이렇게쓴다 주의!!!!!!!!!!!!!!!!!
    -- 그래서 커서를 선언한다기보다는 정의한다.. 가 적합하다...
    CURSOR CUR_INSA_SELECT
    IS
    SELECT NAME,TEL
    FROM TBL_INSA; -- 조회한 많은 데이터들을 꾹 눌러서 담게되는것 실행부에서는 어떻게 구성이 돼야하냐면 
    -- 상자를 열어야 쏟아져나오겠죠 그래서 커서 오픈이 먼저다
    
BEGIN
    -- 커서 오픈 
    OPEN CUR_INSA_SELECT; -- 굉장히 공격적으로 쏟아져나온다. 이렇게 말하는 이유가 있다, 그 데이터들을 받아서 빨리 출력출력출력 해야함
    
    -- 커서 오픈 시 쏟아져나오는 데이터들 처리(잡아내기)
    LOOP
        -- 한 행 씩 끄집어내어 가져오는 행위 ▶ 『FETCH 를 한다고 말함
        FETCH CUR_INSA_SELECT INTO V_NAME,V_TEL;
        
        EXIT WHEN CUR_INSA_SELECT%NOTFOUND;
        
        -- 출력
        DBMS_OUTPUT.PUT_LINE(V_NAME || ' , ' || V_TEL);
    END LOOP;
    
    -- 커서 클로즈
    CLOSE CUR_INSA_SELECT;
END;

우선 배울 때 이해하려고 써놨던 표현들이라서 정말 ㅋㅋㅋㅋㅋㅋㅋㅋ 정리가 안된 것 같지만

생생해서 그냥 남겨두려고 한다. 

커서는 마치 CREATE TABLE 테이블명 이렇게 정의하는 것처럼 생성?한다,

CURSOR 커서이름 IS SELECT 컬럼명 FROM 테이블명;

그 다음 BEGIN 아래에서 

OPEN 커서명; 그다음 OPEN되어 쏟아져나오는 데이터를 받아야 하므로

FETCH 커서명 INTO 변수명;

(FETCH 는 가져온다는 뜻이란다)

위에서는 루프 문 안이기 때문에 만약 CURSOR 에서 나올 데이터가 다 떨어지면 루프문에서 벗어나야 되기 때문에

EXIT WHEN 커서명% NOTFOUND;

를 통해 벗어나게 된다. 이렇게 커서를 다 썻으면 OPEN 했으니 이제 닫아야 한다., CLOSE 커서명;

 

 

 

DECLARE
    V_NAME  TBL_INSA.NAME%TYPE;
    V_TEL   TBL_INSA.TEL%TYPE;
    CURSOR CUR_INSA_SELECT
    IS 
    SELECT NAME, TEL
    FROM TBL_INSA;
BEGIN
    OPEN CUR_INSA_SELECT;
    LOOP
        FETCH CUR_INSA_SELECT INTO V_NAME,V_TEL;
        
        EXIT WHEN CUR_INSA_SELECT%NOTFOUND;
        
        DBMS_OUTPUT.PUT_LINE(V_NAME || ' │ ' || V_TEL);
    END LOOP;
    
    CLOSE CUR_INSA_SELECT;
    

END;


SET SERVEROUTPUT ON;

DECLARE
    V_NAME TBL_INSA.NAME%TYPE;
    V_TEL   TBL_INSA.TEL%TYPE;
    CURSOR CUR_INSA_SELECT 
    IS
    SELECT NAME, TEL
    FROM TBL_INSA;
BEGIN
    OPEN CUR_INSA_SELECT;
    LOOP
        FETCH CUR_INSA_SELECT INTO V_NAME,V_TEL;
        EXIT WHEN CUR_INSA_SELECT %NOTFOUND;
        
        DBMS_OUTPUT.PUT_LINE(V_NAME || ' - ' || V_TEL);
    END LOOP;
    
    CLOSE CUR_INSA_SELECT;
END;

  뭔가 하고 복붙해 보았더니 위에거 외워보겠다고 두 번 다시 써본것 ㅋㅋㅋㅋㅋㅋ 이렇게 반복해도 잘 안외워지긴 마찬가지이다 도대체 나는 몇 번을 반복해야지 되는 걸까 사실은 지금은 커서가 당장 필요해! 쓸거야! 하지를 않아서 그런지 머리에 잘 들어오지를 않는다.