ref cursor 질문드립니다. 1 3 3,204

by 꿈을향해 [PL/SQL] [2018.03.30 00:00:32]


var V_CURSOR REFCURSOR;
execute TEST.PKG_P01.P01_LIST ('abc', 'bcd', 'Y', :V_CURSOR);                     
print V_CURSOR;

위와 같이 실행할 수 있는 PROCEDURE가 있습니다. output으로 단순히 뿌려주기만 하는구조에서

가져온 ref cursor를 다시 open 시키고 조금 조작을 시키려고 아래와 같이 변형Test를하니 wrong number or types of arguments 에러가 나네요. 프로시져 수행후 out변수로 나온 ref cursor를 다시 open시킬 수 있는 방법이 있을까요.?? 아래와 같이 구현하려는 건 아니고 가져온 ref cursor를 다시 open시킬 수 있는지 test차원에서 짜본 코드입니다.

 

DECLARE
    TYPE REFTYPE IS REF CURSOR;
    V_CURSOR REFTYPE;
    
    V_COL1 VARCHAR2(100);
    V_COL2 VARCHAR2(100);
    
BEGIN
    TEST.PKG_P01.P01_LIST ('abc', 'bcd', 'Y', :V_CURSOR); 
    
    OPEN V_CURSOR;
    LOOP    
    FETCH V_CURSOR INTO V_COL1, V_COL2;    
    DBMS_OUTPUT.PUT_LINE(V_COL1);
    EXIT WHEN V_CURSOR%NOTFOUND;
    END LOOP;
    CLOSE V_CURSOR;
    
END;

 

 

by 꿈을향해 [2018.03.30 09:05:34]

아 해결 하였습니다. 프로시져를 수행할때 out변수에 : 를 써주면 해당 에러가 났네요.. 이건 왜그런지 모르겠습니다. out변수를 쓸땐 : 써주는걸로 알고있었는데요. 

그리고 open cursor를 명시해주면 안됬었습니다. 저 프로시져를 호출한다는 자체가 cursor가 open 된다는 개념이더라고요.


by 마농 [2018.03.30 09:06:56]

변수 사용시 콜론(:) 은 빼시구요
커서는 이미 Open 되어 받아온 거니 Open 구문 빼시구요.
Exit 구문은 Fetch 바로 다음으로 옮기세요.
sys_refcursor 를 사용하면 좀더 편리합니다.

DECLARE
    v_cursor SYS_REFCURSOR;
    v_col1 VARCHAR2(100);
    v_col2 VARCHAR2(100);
BEGIN
    test.pkg_p01.p01_list('abc', 'bcd', 'Y', v_cursor);
    LOOP
        FETCH v_cursor INTO v_col1, v_col2;
        EXIT WHEN v_cursor%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE(v_col1);
    END LOOP;
    CLOSE v_cursor;
END;
/

 


by 냥냥펀치원투 [2024.02.20 02:07:35]
PROCEDURE GET_RESULT_CURSOR_COLUMNS_TYPES()
IS

l_rc              SYS_REFCURSOR;
l_cursor_number   INTEGER;
l_col_cnt         INTEGER;
l_desc_tab        DBMS_SQL.desc_tab;
l_col_num         INTEGER;

BEGIN
  -- 다른 패키지의 프로시저 실행
  TEST_SELECT(l_rc);
 
  -- 커서에 대한 컬럼 정보 확인
  l_cursor_number   := DBMS_SQL.to_cursor_number (l_rc);
  DBMS_SQL.describe_columns (l_cursor_number, l_col_cnt, l_desc_tab);
  l_col_num         := l_desc_tab.FIRST;
  
  --커서 결과에 대한 값을 출력
  IF (l_col_num IS NOT NULL) THEN
    LOOP
      DBMS_OUTPUT.put_line ('Column #' || l_col_num);
      DBMS_OUTPUT.put_line ('...name: ' || l_desc_tab (l_col_num).col_name);
      DBMS_OUTPUT.put_line ('...type: ' || l_desc_tab (l_col_num).col_type);
      DBMS_OUTPUT.put_line ('...maxlen: ' || l_desc_tab (l_col_num).col_max_len);
      -- ... other fields available in l_desc_tab(l_col_num) too.
      l_col_num   := l_desc_tab.NEXT (l_col_num);
      EXIT WHEN(l_col_num IS NULL);
    END LOOP;
  END IF;
  
  --커서 닫기
  DBMS_SQL.close_cursor (l_cursor_number);
END;

마농님 질문이 있습니다.

FETCH INTO 를 하기 위해서는 변수가 필요한데

아래와 같은 프로시저로 결과값 커서에 대한 컬럼명을 확인해서 RECORD 타입이나 변수를 선언해서 FEATCH를 사용 해야 됩니다.

이러한 과정 없이 커서 결과값을 받는 방법이 있을까요?

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입