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;
아 해결 하였습니다. 프로시져를 수행할때 out변수에 : 를 써주면 해당 에러가 났네요.. 이건 왜그런지 모르겠습니다. out변수를 쓸땐 : 써주는걸로 알고있었는데요.
그리고 open cursor를 명시해주면 안됬었습니다. 저 프로시져를 호출한다는 자체가 cursor가 open 된다는 개념이더라고요.
변수 사용시 콜론(:) 은 빼시구요
커서는 이미 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;
/
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를 사용 해야 됩니다.
이러한 과정 없이 커서 결과값을 받는 방법이 있을까요?