pl/sql구문 for문안에 SELECT DENSE_RANK ()함수 0 10 1,295

by 아이린 [PL/SQL] [2017.01.31 13:57:11]


아래 프로시져 구문에서 for문안에 select구문의 DENSE_RANK ()함수에  OREDER BY 절에  변수 V_STD_CD1, V_STD_CD2, V_STD_CD3, V_STD_CD4, V_STD_CD5를 못넣나요? 값은 해당 테이블의 컬럼이며 위 변수 5개의 조건을 넣을때도 있고 안넣을때도 있으며 넣은 값은 같은 ROW 번호를 매겨서 포문을 돌리려고 하는데 잘안되네요 ㅠ고수님들 도와주세요

FOR ROW_NO IN(

SELECT SEQ_NO

FROM(

SELECT DENSE_RANK ()
          OVER (ORDER BY
                   V_STD_CD1,
                   V_STD_CD2,
                   V_STD_CD3,
                   V_STD_CD4,
                   V_STD_CD5) SEQ_NO

)GROUP BY SEQ_NO

)

by 마농 [2017.01.31 14:13:28]

변수를 Order By 절에 넣을 수는 있습니다.
다만 원하는대로 동작하지는 않을 것입니다.
변수의 값은 고정값이니 고정값으로의 정렬은 무의미합니다.
Dense_rank 의 결과는 모두 동일하게 1 이 나올 것입니다.


변수에 저장되어 있는 컬럼명으로의 정렬을 원하신다면?
위와 같은 방법으로는 안됩니다.
동적 쿼리를 이용하셔야 합니다.
http://www.gurubee.net/article/19612


by 아이린 [2017.01.31 14:36:02]

마농님 답변 감사합니다
A. 조건테이블

번호 기준1 기준2 기준3 기준4 기준5
1 고객사   출고예정    
2   고객사 출고예정    

 

B. 속해져 있으며 얻고자하는 값 테이블

번호 센터 고객사 구분 상태 출고예정 결과값
1006 100 1001 11 10 20170124 1
1007 100 1001 11 10 20170124 1
1004 100 1002 11 10 20170120 2
1005 100 1002 11 10 20170120 2

 

A.조건 테이블의 기준을 가지고 B테이블 에서는 그 기준에 속해져있는 컬럼에 값을 가지고

같은거 끼리는 번호를 같게 할려고 한 것입니다 ㅜ잘안되네요 도와주세요


by 마농 [2017.01.31 15:18:04]

원하는 결과값은 Dense_rank 로 구할 수 있습니다.
다만, 정렬 기준이 변수처리 된다면?
동적 쿼리를 이용해야 합니다.


by 아이린 [2017.01.31 15:49:43]

동적쿼리는 뭔가 고정된 데이터 값을 받아서 처리하는거 아닌가요?

조건값  컬럼의 데이터가  같은 것이 주가되서 묶어줘야 해서요 그걸 위에 DENSE_RANK의 함수에 ORDER BY 값에 A.조건테이블 변수를 주어서 구할려고 한거였는데 안되네요 방법이 생각이 나질 않아서 도움요청 합니다. ㅠ


by 마농 [2017.01.31 15:56:40]

동적쿼리의 개념을 잘못 생각하고 계신 듯 하네요.
동적쿼리를 어떤 특정 상황에서만 사용할 수 있는 걸로 생각하고 계신 듯.
동적쿼리는 단순하게 생각하면 쿼리문장이 따옴표로 감싸진 것일 뿐입니다.
쿼리 문장이 변수에 저장되어 있고, 이를 동적으로 변경 가능한 것일 뿐입니다.
정렬 구문 부분을 동적으로 구성하셔서 실행하는 방식으로 하시면 됩니다.
동적 쿼리 사용법은 위 참고 URL 보시고 공부좀 하셔야 합니다.


by 아이린 [2017.01.31 16:02:56]

네 감사합니다


by jkson [2017.01.31 16:11:51]

예시 올려드릴게요. 보시면 뭔지 이해가 되실 겁니다. 주석 처리된 부분 해제하면서 번갈아서 실행해보세요.

DECLARE
 V_SQL VARCHAR2(4000);
 VAL  VARCHAR2(10);
 TYPE CUR IS REF CURSOR;
 C1   CUR;
BEGIN
 V_SQL       :=
  Q'[SELECT SEQNO                                        ]' ||
  Q'[  FROM (SELECT 1 SEQNO, 'C' TXT FROM DUAL UNION ALL ]' ||
  Q'[        SELECT 2      , 'B'     FROM DUAL UNION ALL ]' ||
  Q'[        SELECT 3      , 'A'     FROM DUAL)          ]';

 IF 1 = 1 THEN
 --IF 1 != 1 THEN
  V_SQL       := V_SQL || 'ORDER BY SEQNO';
 ELSE
  V_SQL       := V_SQL || 'ORDER BY TXT';
 END IF;

 OPEN C1 FOR V_SQL;

 LOOP
  FETCH C1 INTO VAL;
  EXIT WHEN C1%NOTFOUND;
  DBMS_OUTPUT.PUT_LINE(VAL);
 END LOOP;
END;

 


by 아이린 [2017.01.31 16:18:49]

네 감사합니다


by 마농 [2017.01.31 16:38:24]

emp 테이블을 읽어 출력하는 프로그램 한번 만들어 봤습니다.

참고하세요.

DECLARE
    v_std_cd1 VARCHAR2(10) := 'deptno';
    v_std_cd2 VARCHAR2(10) := 'job';
    v_std_cd3 VARCHAR2(10) := '';
    v_std_cd4 VARCHAR2(10) := '';
    v_std_cd5 VARCHAR2(10) := '';
    v_sql VARCHAR2(4000);
    v_ord VARCHAR2(100);
    TYPE ref_cur IS REF CURSOR;
    rc ref_cur;
    TYPE emp_rec_type IS RECORD( empno    emp.empno   %TYPE
                               , ename    emp.ename   %TYPE
                               , job      emp.job     %TYPE
                               , mgr      emp.mgr     %TYPE
                               , hiredate emp.hiredate%TYPE
                               , sal      emp.sal     %TYPE
                               , comm     emp.comm    %TYPE
                               , deptno   emp.deptno  %TYPE
                               , seq_no   NUMBER(3)
                               );
    emp_rec emp_rec_type;
BEGIN
    v_sql := v_sql || 'SELECT empno, ename, job, mgr, hiredate, sal, comm, deptno ';
    v_sql := v_sql || ' , DENSE_RANK() OVER(ORDER BY 1/* 요기 */) seq_no ';
    v_sql := v_sql || ' FROM emp ';
    v_ord := v_ord || CASE WHEN v_std_cd1 IS NOT NULL THEN ','||v_std_cd1 END;
    v_ord := v_ord || CASE WHEN v_std_cd2 IS NOT NULL THEN ','||v_std_cd2 END;
    v_ord := v_ord || CASE WHEN v_std_cd3 IS NOT NULL THEN ','||v_std_cd3 END;
    v_ord := v_ord || CASE WHEN v_std_cd4 IS NOT NULL THEN ','||v_std_cd4 END;
    v_ord := v_ord || CASE WHEN v_std_cd5 IS NOT NULL THEN ','||v_std_cd5 END;
    v_sql := REPLACE(v_sql, '/* 요기 */', v_ord);
    OPEN rc FOR v_sql;
    LOOP
        FETCH rc INTO emp_rec;
        EXIT WHEN rc%NOTFOUND;
        dbms_output.put_line( RPAD(emp_rec.empno    , 4, ' ')
                    ||' | '|| RPAD(emp_rec.ename    , 9, ' ')
                    ||' | '|| RPAD(emp_rec.job      , 9, ' ')
                    ||' | '|| RPAD(emp_rec.mgr ||' ', 4, ' ')
                    ||' | '|| TO_CHAR(emp_rec.hiredate, 'yyyy.mm.dd')
                    ||' | '|| LPAD(emp_rec.sal      , 4, ' ')
                    ||' | '|| LPAD(emp_rec.comm||' ', 4, ' ')
                    ||' | '|| LPAD(emp_rec.deptno   , 2, ' ')
                    ||' | '|| LPAD(emp_rec.seq_no   , 2, ' ')
                    );
    END LOOP;
END;
/

 


by 아이린 [2017.01.31 16:49:56]

네 마농님 정말 감사합니다 치환을 해서 넣는 방법을 몰랐네요 ^^

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