오라클 동적 쿼리 오류 질문입니다.. 0 4 1,384

by VANT [PL/SQL] [2020.09.03 09:48:40]


안녕하세요.

제가 오류가 계속 나는데 잡질 못하겠어서 여쭤봅니다.

이번에 동적 쿼리란걸 찾아보면서 이렇게 만들어보았습니다.

 

테이블이 DAILY_20200101부터 일자별로  DAILY_2020831 까지 저장되어 있는데요,

따라서 조회를 2개의 날짜를 받아서 해당 테이블들을 가져와서,

테이블들을 모두 UNION ALL 하는 형태로 조회가 이루어져야되는 상황입니다.

이 경우, UNION ALL은 어려운 거 같아서 이렇게 쿼리를 짜봤습니다.

한참했는데.. 오류가 도저히 잡히질 않아요..

 

CREATE OR REPLACE PROCEDURE PROC_SELECT_TBL

(

  START_DATE IN NUMBER,

  END_DATE IN NUMBER

)

IS

  TYPE TBL_LIST IS TABLE OF VARCHAR2(1000) INDEX BY PLS_INTEGER; 

  TYPE SELECT_ROWS IS TABLE OF DAILY_20200101%ROWTYPE INDEX BY PLS_INTEGER;

  V_TBL_LIST TBL_LIST;

  V_ROWS SELECT_ROWS;

  SQL_STR VARCHAR2(100);

  RES_STR VARCHAR2(100);

  R_CUR SYS_REFCURSOR;

  V_CUR SYS_REFCURSOR;

  RES_CUR SYS_REFCURSOR;

BEGIN

    SQL_STR := 'SELECT TNAME FROM TAB WHERE SUBSTR(TNAME, 7) BETWEEN :START_DATE AND :END_DATE';

    

    OPEN V_CUR FOR SQL_STR USING START_DATE, END_DATE;

    LOOP

        FETCH V_CUR BULK COLLECT INTO V_TBL_LIST;

        EXIT WHEN V_CUR%NOTFOUND;

    END LOOP;

    CLOSE V_CUR;

 

    FOR IDX in 1..V_TBL_LIST.LAST

    LOOP

        RES_STR := 'SELECT * FROM TRIM(V_TBL_LIST(:IDX))';

        OPEN RES_CUR FOR RES_STR USING IDX;

        LOOP

            FETCH RES_CUR BULK COLLECT INTO V_ROWS;

            EXIT WHEN RES_CUR%NOTFOUND;

        END LOOP;

    END LOOP;

END;

/

 

SET SERVEROUTPUT ON;

EXEC PROC_SELECT_TBL(20200103, 20200105);

이렇게 쓰면

명령의 39 행에서 시작하는 중 오류 발생 -

BEGIN PROC_SELECT_TBL(20200103, 20200105); END;

오류 보고 -

ORA-00933: SQL 명령어가 올바르게 종료되지 않았습니다

ORA-06512: "UJWSO.PROC_SELECT_TBL",  29행

ORA-06512:  1행

00933. 00000 -  "SQL command not properly ended"

*Cause:    

*Action:

꼭 저 검은줄에서 오류가 나고요, 오류 명이 바뀌지도 않고

SQL을 이렇게 저렇게 바꿔도 똑같이 SQL이 제대로 종료되지 않았다는 오류가 뜹니다.

 

어떻게 고쳐야 하나요 ㅠㅠ ?

저렇게 테이블 이름 슬라이싱으로 테이블들을 조회하고,

그 테이블들을 한데 묶어서 조회할 수 있어야 합니다..(UNION ALL 처럼)

조언 부탁드립니다.

by 마농 [2020.09.03 11:20:10]

뷰를 이용하는 쉬운 방법 알려드렸는데. 어려운 방법을 시도하시네요.
 - 오류 : RES_STR := 'SELECT * FROM TRIM(V_TBL_LIST(:IDX))';
 - 수정 : RES_STR := 'SELECT * FROM ' || TRIM(V_TBL_LIST(IDX));
이 방식을 이용하려면 넘어야 할 산이 많을 것 같습니다.
뷰를 이용하시면 참 쉬운데요.


by VANT [2020.09.03 11:25:46]

네 저도 그 답변을 기억하고 있습니다..

근데 제가 잘 머리속에 그려지지가 않는데, 테이블이 하루마다 더 생기더라도

뷰를 계속 만들고 조회하는게 효율적인가요??

 

제가 잘 몰라서 여쭤봅니다.. 제 가정은 하루마다 테이블이 하나씩 늘어나는데 매번 그 떄마다 뷰를 만들어주는게

더 효율적이라면, 그 방법으로도 해보겠습니다~~!


by 마농 [2020.09.03 12:23:16]

테이블이 하루하루 관리되고 있다면?
뷰 또한 하루 하루 갱신해주면 됩니다.
지금 하고 있는 방식이 틀렷다는게 아니라, 더 쉬운 방법이 있는데 굳이 어려운 방법을 사용하는가? 하는 거죠.
굳이 이렇게 하고자 한다면? 관련 정보를 찾아서 개발해야 하는데.
이게 산넘어 산입니다. 접목시켜야할 정보가 상당합니다.
지금 동적쿼리에서 좀 헤매이고 계신데.
이거 해결하고 나면 다음은 멀티로우를 어떤 방식으로 전달할 것인가 고민하셔야 합니다.

테이블 구조를 바꿀 수는 없나요?
파티션 테이블을 사용하면 좋을 텓데요.


by VANT [2020.09.03 12:45:30]

그렇군요.

뷰 또한 이렇게 모든 테이블을 조회하는 걸 만들어놓고 매일 매일 추가적으로 갱신하면 된다는 얘기시지요??

감사합니다. 해보겠습니다..ㅎㅎ

 

파티션 테이블은 아직 제가 할 만한 수준이 아닌 것 같아서 차근차근히 해보겠습니다....ㅎㅎ!

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