[ Oracle - Procedure 문법_LOOP문 ]

 

1. 문법

LOOP

 

statement;

...

EXIT [WHEN condition];

 

END LOOP;

 

2.예제

   ex) ...

          v_ord_id s_item.ord_id%TYPE := 101;

          v_counter NUMBER(2) := 1;

        BEGIN

          ...

        LOOP

          INSERT INTO s_item (ord_id, item_id)

          VALUES (v_ord_id, v_counter);

                        v_counter := v_counter + 1;

        EXIT WHEN v_counter > 10;

        END LOOP;

         ...

'(DB) Oracle > PL.SQL' 카테고리의 다른 글

Oracle - Procedure 문법_DBMS_OUTPUT  (0) 2017.01.21
Oracle - Procedure 문법_WHILE문  (0) 2017.01.21
Oracle - Procedure 문법_IF문  (0) 2017.01.21
Oracle - Procedure 문법_FOR_LOOP문  (0) 2017.01.21
Oracle - Procedure 문법_CASE문  (0) 2017.01.21
Posted by 농부지기
,

[ Oracle - Procedure 문법_IF문 ]

 

1. 기본 문법

2. if문에 in 사용법

3. if문에 exists 사용법

4. if문에 between 사용법

1.문법 (기본식)

    IF condition THEN

        statement;

   [ELSIF condition THEN

        statement;]

   [ELSE

       statement;]

    END IF;

2. 문법(in)

     If 문의 비교 부분에 IN 을 넣을 수 있음

     예]

     if   (x_bill_gubun2   IN   (1,2,3,6)) then x_sum:=x_sum+x_bill_amt;

3. 문법(Exists)

    if exists(select * from inserted where J_NAME='ABC') begin

         ....

    end

    * count 를 할 필요 없이.. 그냥 * 로 하면 됨..

4. IF 문을 from ~ to 로 하는 경우

    IF iRtnMonth between 1 and 11 THEN

       .....

    END IF

 

 

 

Posted by 농부지기
,

[ Oracle - Procedure 문법_FOR_LOOP문 ]

 

1.문법

    FOR index in [REVERSE] lower_bound..upper_bound LOOP

          statement;

    END LOOP;

2.예제

  ex) 우선 set serveroutput on을 한다.

       CREATE OR REPLACE PROCEDURE iterate

          (v_lower NUMBER,    v_upper NUMBER)

       IS

           v_counter NUMBER(10) := 0;

           v_output NUMBER(10);

       BEGIN

           FOR i IN v_lower..v_upper LOOP

                  v_counter := v_counter + 1;

                  v_output := i;

           END LOOP;

 

           DBMS_OUTPUT.PUT_LINE('Last value is '||TO_CHAR(v_output)  ||'. Total loops = '||TO_CHAR(v_counter));

      END iterate;

3. 예제 2

    설명 : - 1~150까지 1씩 증가 하면서 LOOP를 돈다.

    문법 :

          FOR nLoop IN 1..150 LOOP

                 ............

          END LOOP;

 

 

Posted by 농부지기
,

[ Oracle - Procedure 문법_CASE문 ]

 

CASE의 유형

 

- CASE 수식은 다음과 같이 사용할 수 있습니다.

    . 임의의 SQL 수식과 유사한 방법으로 쓰입니다.

    . 대입문의 변수로서, 그리고 SQL 문 또는 논리 연산의 일부로서 사용할 수 있습니다.

    . 키워드 CASE로 시작하여 END로 끝이 납니다.

- CASE 문은 다음과 같이 사용할 수 있습니다.

    . IF…THEN…ELSE 구문과 유사하게 독립적인 문장으로 쓸 수 있습니다.

    . 키워드 CASE로 시작하여 END CASE로 끝이 납니다.

- 단순 CASE :

    . 단일의 변수/수식에 대하여 복수의 값에 대해 적용됩니다.

    . WHEN 절 내에 비교 연산자를 쓸 수 없습니다.

-  검색 CASE :

    .  보다  유연하게  쓸  수  있습니다.

    .  각각의 WHEN  절은

        o  필요하다면  서로  다른  변수들을  사용할  수  있습니다.

        o  비교  연산자를  쓸  수도  있습니다.

 

예: 단순 CASE 수식)

    CREATE OR REPLACE FUNCTION get_comm (p_comm NUMBER)

     RETURN VARCHAR2 IS

               v_comm VARCHAR2(10);

    BEGIN

             v_comm :=    CASE p_comm

                                 WHEN .15 THEN 'fifteen percent'

                                 WHEN .2  THEN 'twenty percent'

                                 ELSE 'thirty percent'

                                 END;

              RETURN v_comm;

    END;

 

예: 단순 CASE 문)

    CREATE OR REPLACE FUNCTION get_comm (p_comm NUMBER)

        RETURN VARCHAR2 IS

              v_comm VARCHAR2(10);

    BEGIN

             CASE p_comm

                      WHEN .15 THEN

                             v_comm := 'fifteen percent';

                      WHEN .2 THEN

                             v_comm := 'twenty percent';

                      ELSE  

                             v_comm := 'thirty percent';

            END CASE;

            RETURN v_comm;

     END;

 

예: 검색 CASE 수식)

    CREATE OR REPLACE FUNCTION get_sal_grade (p_sal NUMBER)

        RETURN VARCHAR2 IS

           v_grade VARCHAR2(25);

   BEGIN

           v_grade :=  CASE

                             WHEN p_sal < 10000 THEN

                                       'salary is low'

                             WHEN p_sal BETWEEN 10000 AND 50000 THEN

                                       'salary is average'

                             ELSE

                                      'salary is high'

                             END;

            RETURN v_grade;

    END;

 

예: 검색 CASE 문)

    CREATE OR REPLACE FUNCTION get_raise (p_sal NUMBER)

    RETURN VARCHAR2 is

                v_raise VARCHAR2(10);

    BEGIN

               CASE

                          WHEN p_sal < 10000 THEN

                                     v_raise :='raise is 10%';

                          WHEN p_sal >= 10000 THEN

                                    v_raise := 'raise is 15%';  

                         END CASE;

             RETURN v_raise;

    END;

 

 

 

Posted by 농부지기
,

[ Oracle - Procedure 문법_선언문(Declare) ]

 

1) 테이블의 열의 type으로 변수선언

   %type은 열의 구조만 가져온다.

 

2) %rowtype : 해당 테이블의 모든 컬럼과 type으로 변수선언

    테이블이나 뷰 내부의 컬럼 데이터형, 크기, 속석등을 그대로 사용할수 있습니다.

    ⊙  %ROWTYPE 앞에 오는 것은 데이터 베이스 테이블 이름입니다.

    ⊙  지정된 테이블의 구조와 동일한 구조를 갖는 변수를 선언할수 있습니다.

    ⊙  데이터베이스 컬럼들의 수나 DATATYPE을 알지 못할 때 편리 합니다.

    ⊙  테이블의 데이터 컬럼의 DATATYPE이 변경될 경우 프로그램을 재수정할 필요가 없습니다

    주의) not null 제한은 포함안됨.

      예)   변수명  TABLE_NAME%ROWTYPE;

 

3) 배열선언

    형식) TYPE 정의명 IS TABLE OF 타입 INDEX BY BINARY_INTEGER;

          배열정  정의명;

    예)   TYPE t_val IS TABLE OF VARCHAR2(50) INDEX BY BINARY_INTEGER;

          arr_val  t_val;

    사용예)   arr_val(0)   := '1234';

              arr_val(100) := 'asdf';

              괄호()를 안에 integer값(변수)를 사용해서 배열에 값을 넣거나 사용할 수 있다.

4) 변수 선언

   declare

       cnt    number(4);

       qty    number(11,3);

       errnum char(6):='-20999';                  --> 초기 할당 방법

 

5) 모든 변수 TYPE 선언

    BINARY_INTEGER

    NUMBER [(전체자리수, 소수점이하자릿수)]

    CHAR : 한문자

    CHAR(n)

    LONG

    LONG RAW

    VARCHAR2 (n) : 문자형중에서 가장 많이 사용

    DATE

    BOOLEAN : TRUE, FALSE

------------------------------------------------------------------------------

1. 테이블 변수의 type으로 변수 선언

   문법 :  v_f_apply_ymd   ODM_SHIFT_WORK_DAILY.apply_ymd%TYPE := '';

 

   설명 :  - ODM_SHIFT_WORK_DAILY 은 테이블 명

              - apply_ymd 은 ODM_SHIFT_WORK_DAILY  테이블의 컬럼 명

 

2. 배열 선언

    문법 : TYPE arr_holiday_work_hour  IS TABLE OF ODM_SHIFT_WORK_LIST.appl_holiday_work_hour%TYPE

                    INDEX BY BINARY_INTEGER;

              holiday_work_hour_arr arr_holiday_work_hour;

 

    설명 : - ODM_SHIFT_WORK_LIST : 테이블명

             - appl_holiday_work_hour  : ODM_SHIFT_WORK_LIST 테이블의 컬럼명

             - arr_holiday_work_hour   : 배열변수명

                                                        ODM_SHIFT_WORK_LIST.appl_holiday_work_hour 컬럼의 type으로 배열변수 정의

 

             - 이유는 모르겠지만 위에서 생성된  배열변수를 다시 아래에서 재 정의 후 아래

                 holiday_work_hour_arr 를  source에서 사용 된다.

 

      * 참고: source에서 사용법

                문법 :  holiday_work_hour_arr(숫자변수) := value;

 

3. error 처리 변수 선언

   문법 : SQL_ERROR_RTN   EXCEPTION;

   설명 : 모름???

 

4. 테이블 컬럼 모두를 한번에 변수 정의

   문법 : v_py  py_payroll%ROWTYPE;

   설명 : - 만약 py_payroll 테이블의 컬럼이 pay_ymd, pay_type, p001, p002, p003 이 존재 할 경우

             - v_py.pay_ymd,    v_py.pay_type,     v_py.p001,     v_py.p002,     v_py.p003  변수를 모두 사용 할 수 있다.

             - 보통 package정의 시 많이 사용 되며, package정의 시에  정의 되었을 경우

                종속된 procedure에서는   package_name.v_py.컬럼명     과 같이 사용 된다.

 

'(DB) Oracle > PL.SQL' 카테고리의 다른 글

Oracle - Procedure 문법_IF문  (0) 2017.01.21
Oracle - Procedure 문법_FOR_LOOP문  (0) 2017.01.21
Oracle - Procedure 문법_CASE문  (0) 2017.01.21
Oracle - Procedure를 바로 실행하기  (0) 2017.01.21
Oracle - PROCEDURE 개념  (0) 2017.01.21
Posted by 농부지기
,

[ Oracle - Procedure를 바로 실행하기 ]

 

 

vDECLARE 
  P_ACCOUNTUNITCD VARCHAR2(200);
  P_BUDGETYEAR VARCHAR2(200);
  P_USERID VARCHAR2(200);

BEGIN 
  P_ACCOUNTUNITCD := '''TBD0001''';
  P_BUDGETYEAR := '''2010''';
  P_USERID := '''MIG''';
 
  ETISAC.BY_BUDGETSUM_RESET_PR1 ( P_ACCOUNTUNITCD, P_BUDGETYEAR, P_USERID );
  COMMIT; 
END;


 

'(DB) Oracle > PL.SQL' 카테고리의 다른 글

Oracle - Procedure 문법_IF문  (0) 2017.01.21
Oracle - Procedure 문법_FOR_LOOP문  (0) 2017.01.21
Oracle - Procedure 문법_CASE문  (0) 2017.01.21
Oracle - Procedure 문법_선언문(Declare)  (0) 2017.01.21
Oracle - PROCEDURE 개념  (0) 2017.01.21
Posted by 농부지기
,

[ Oracle - PROCEDURE 개념 ]

 


☞ 개요

  1. 정의 : Oracle에서 지원하는 프로그램 언어의 특성을 수용한 SQL의 확장`
2. 처리 환경
   

 

3. 처리절차
   PL/SQL로 작성된 Block를 Oracle Server로 보내면 그 안에 있는 PL/SQL Engine이 SQL문과 
   Non-SQL문을 구별한다. Non-SQL문은 엔진내의 Procedural Statement Executor가 수행하고 
   SQL문은 SQL Statement Executor이 처리하게 된다. 즉, Non-SQL은 Client환경에서 처리되고 
   SQL문은 Server에서 수행됩니다. 따라서 PL/SQL을 사용하면 Server쪽으로 보내지는 작업의 
   양이 줄어들므로 Network Traffic을 감소시켜 
Performance를 증가시키는 이점이 있다.


 PL/SQL의 기본 BLOCK

  

ㅇ 기본적인 PL/SQL 블럭 구조는 세 부분으로 구성됨
    


    - 선언부 : 실행부에서 참조할 모든 변수, 상수 , Cursor, Exception을 선언
    - 실행부 : 데이터베이스의 데이터를 처리할 SQL문과 블럭안의 데이터를 처리할 PL/SQL문을 기술

- 에러처리부 : 실행부에서 에러와 비정상적인 조건이 발생했을 때 수행될 문장을 기술

ㅇ Function의 구조 : 반드시 하나의 값을 돌려줘야 되는 경우 

 형식)
CREATE [OR REPLACE] FUNCTION function명
     [ (parameter1 parameter타입 parameter데이터타입 ,
         parameter2, ...) ]
       RETURN 데이터타입
     IS
       변수선언
     BEGIN
       RETURN(값 );
     EXCEPTION
     END ;

ㅇ Procedure의 구조

형식)
     CREATE [OR REPLACE] FUNCTION function명
     [ (parameter1 parameter타입 parameter데이터타입 ,
         parameter2, ...) ]
       RETURN 데이터타입
     IS
       변수선언
     BEGIN
       RETURN(값 );
     EXCEPTION
     END ;

 

 Paramenter 타입 및 선언 방법

  

 ㅇ 3가지 타입이 존재
     


 

 

☞ 2. 변수의 선언

 

(1) 변수 선언 방법
    형식) Identifier명 [CONSTANT] 데이터타입 [NOT NULL] [:= 상수값이나 표현식] ;

(2) Scalar 타입

데이터 타입

설    명

BINARY_INTEGER

- 2147483647에서 2147483647사이의 정수

PLS_INTEGER

- 2147483647에서 2147483647사이의 부호 표시 정수
- 저장 공간을 적게 사용하고 NUMBER나 BINARY_INTEGER보다 빠름

NUMBER[(p,s)]

- 고정 및 부동 소숫점 수

CHAR[(n)]

- 32767바이트까지의 고정길이 문자, n을 지정하지 않으면 1로 설정

LONG

- 32767바이트까지의 가변길이 문자

VARCHAR2(n)

- 32767바이트까지의 가변길이 문자

DATE

- 날짜와 시각

BOOLEAN

- 논리(TRUE, FALSE, NULL)


(3) Reference Type 변수
ㅇ %TYPE Attribute : 변수의 데이터타입을 데이터베이스 컬럼에 맞추어 선언
예제)
DECLARE
   v_name               s_emp.name%TYPE;
   v_salary           s_emp.salary%TYPE;
   v_num             NUMBER(5,2) ;
   v_total_num        v_num%TYPE ;

ㅇ %ROWTYPE Attribute : Record를 선언할 때 컬럼명과 데이터 타입을 그대로 가져옴
형식)
DECLARE
   dept_record          s_dept%ROWTYPE;

(4) Composite Type 변수
ㅇ TABLE Type : C의 배열과 유사, 동적으로 커질 수 있음.

형식)
     DECLARE
     TYPE Type이름 IS TABLE OF scalar데이터타입  [NOT NULL]
             INDEX BY BINARY_INTEGER ;
     Identifier이름     Type이름;

예제 1) 사원의 이름을 저장하는 변수 선언
DECLARE
   TYPE 
name_table_type IS TABLE OF s_emp.name%TYPE
      INDEX BY BINARY_INTEGER;
   
name_table         name_table_type;

예제 2) 사원의 모든 정보를 저장
     DECLARE
        TYPE emp_table_type IS TABLE OF s_emp%ROWTYPE
     
      INDEX BY BINARY_INTEGER;
        emp_table         emp_table_type;

ㅇ RECORD Type : 구조체와 유사
예제1)
DECLARE
   TYPE 
emp_record_type IS RECORD
   (id          NUMBER(7),
   name         VARACHAR2(25),
   start_date DATE  NOT NULL := SYSDATE );
   emp_record         
emp_record_type ;

(5) 기타 변수
ㅇ LOB : 텍스트, 그래픽, 이미지, 비디오파일 ,사운드 등을 4GB까지 저장
ㅇ BiND 변수 : 호스트 환경에서 선언한 변수로서 Run Time 값을 하나 이상의 PL/SQL 프로그램과 
               주고 받는데 사용

    SQL> VARIABLE a NUMBER
    SQL> PRINT a
ㅇ HOST 변수 : 참조대상에 콜론(:)을 접두어로 붙여서 PL/SQL의 변수와 구분을 하여 사용

예제)
VARIABLE b_avg NUMBER
ACCEPT b_math PROMPT 'Input math value :'
ACCEPT b_eng PROMPT 'Input english value :'
DECLARE
       v_math   NUMBER(9,2) := &b_math ;
       v_eng    NUMBER(9,2) := &b_eng  ;
BEGIN
       :b_avg := (v_math + v_eng )/2 ;
END;
/
PRINT b_avg


 

 

Posted by 농부지기
,

[ Oracle - wm_concat ]

 


1.  
Oracle 에는 비공개된 숨겨진 functions  parameter 다수 존재합니다.

     그 중에서 최근에 알게  것이 "wmsys.wm_concat"라는 함수로 굉장히 강력합니다.

     기능적으로 보면 집약하는 함수라고   있으며, 정규화된 table 비정규화해서 출력하는

     경우에 딱맞습니다. Oracle11g manual에는 기재되어 있지 않기 때문에

     undocumented function(support대상외)이라는 것을 알고 사용하기를 바랍니다.

 

2.  이제 어떤 기능이 되는지 살펴보겠습니다. 우선 다음과 같은 간단한 table 만들어 보겠습니다.

name

description

userid

 

point

취득한 point

getdate

point취득일

 

3.  point 발생할 때마다 table new record 등록이 되므로 userid별로 복수의 records

  존재하게 됩니다. 이렇게 정규화된 table에서 비정규화된 형태(userid별로 point취득일과

  취득한 point 다음의 결과와 같이  행에 표시) 출력하고자 하는 경우에

    wm_concat 사용할  있습니다.

SQL> create table points (userid varchar2(20), point number(10), getdate date);

SQL> insert into points values ('hurjin',100,to_date('2009/04/19','yyyy/mm/dd'));

SQL> insert into points values ('hurjin',50,to_date('2009/05/20','yyyy/mm/dd'));

SQL> insert into points values ('hurjin',300,to_date('2009/05/10','yyyy/mm/dd'));

SQL> insert into points values ('myoyoung',1100,to_date('2009/03/29','yyyy/mm/dd'));

SQL> insert into points values ('myoyoung',40,to_date('2009/04/19','yyyy/mm/dd'));

SQL> insert into points values ('myoyoung',150,to_date('2009/05/01','yyyy/mm/dd'));

SQL> select userid, wmsys.wm_concat(point || '(' || getdate || ')') point_info

   2    from points group by userid order by userid;

userid

point_info

hurjin

100(2009-04-19),300(2009-05-10),50(2009-05-20)

myoyoung

1100(2009-03-29),40(2009-04-19),150(2009-05-01)

 

 

4.  보통 위와 같은 결과를 얻기 위해서는 application쪽에서 coding 하는 경우가 많습니다만,

     wm_concat 사용함으로서  번의 SQL 수행을 통해 결과를 얻을  있습니다.

 

5.   wmsys Workspace Manager metadata 저장하기 위한 schema인데,

     wm_concat함수의 source 암호화되어 있는 관계로  수는 없어서 어떤 식으로 처리를 하는지

      수는 없습니다. 하지만 실행속도는 native function 비슷한 정도로,

     대량의 data test 경우에도 처리속도가 훌륭하더군요.

     아래에서는  하나의 예입니다.

SQL> create table idtable (id number, val varchar2(20));

SQL> insert into idtable (id, val) values (10, 'abc');

SQL> insert into idtable (id, val) values (10, 'abc');

SQL> insert into idtable (id, val) values (10, 'def');

SQL> insert into idtable (id, val) values (10, 'def');

SQL> insert into idtable (id, val) values (20, 'ghi');

SQL> insert into idtable (id, val) values (20, 'jkl');

SQL> insert into idtable (id, val) values (20, 'mno');

SQL> insert into idtable (id, val) values (20, 'mno');

SQL> commit;

SQL> column enames format a50;

 

SQL> select id, wmsys.wm_concat(val) as enames from idtable group by id;

id

val

10

abc,abc,def,def

20

ghi,jkl,mno,mno

 

SQL> select id, wmsys.wm_concat(distinct val) as enames

    2   from idtable group by id order by id;

id

val

10

abc,def

20

ghi,jkl,mno

 

SQL> select id, val, wmsys.wm_concat(val) over(partition by id) as enames

    2   from idtable order by id;

id

val

enames

10

abc

abc,abc,def,def

10

abc

abc,abc,def,def

10

def

abc,abc,def,def

10

def

abc,abc,def,def

20

ghi

ghi,jkl,mno,mno

20

jkl

ghi,jkl,mno,mno

20

mno

ghi,jkl,mno,mno

20

mno

ghi,jkl,mno,mno

 

SQL> select id, val, wmsys.wm_concat(val) over(order by id, val) as enames

2   from idtable order by id;

id

val

enames

10

abc

abc,abc

10

abc

abc,abc

10

def

abc,abc,def,def

10

def

abc,abc,def,def

20

ghi

abc,abc,def,def,ghi

20

jkl

abc,abc,def,def,ghi,jkl

20

mno

abc,abc,def,def,ghi,jkl,mno

20

mno

abc,abc,def,def,ghi,jkl,mno

 

 

6.  database를 DBCA를 이용하지 않고 수동으로 생성하여 "wmsys" schema가 존재하지 않는 경우,

     "$ORACLE_HOME/rdbms/admin/owminst.plb"를 실행하여 생성할 수 있습니다.

'(DB) Oracle > SQL.통계-Connect by' 카테고리의 다른 글

Oracle - connect_by_isleaf  (0) 2017.01.21
Oracle - Connect_By  (0) 2017.01.21
Posted by 농부지기
,

[ Oracle - 레코드를 하나의 컬럼으로 결합 ]

 

 


 


WITH t(type, name, code) AS
(
              
SELECT '과일', '사과', '0' FROM dual
    
UNION ALL SELECT '과일', '레몬', '1' FROM dual
    
UNION ALL SELECT '과일', '포도', '2' FROM dual
    
UNION ALL SELECT '과일', '참외', '3' FROM dual
    
UNION ALL SELECT '채소', '오이', '0' FROM dual
    
UNION ALL SELECT '채소', '당근', '1' FROM dual
    
UNION ALL SELECT '채소', '호박', '2' FROM dual
)
SELECT type
     , 
SUBSTR(XMLAgg(XMLElement(x, ',', name) ORDER BY code).Extract('//text()'), 2) name_9i
     , 
wm_concat(name) name_10g
     , 
ListAgg(name, ',') WITHIN GROUP(ORDER BY code) name_11g
  
FROM t
 
GROUP BY type
 
ORDER BY type ;

 

Posted by 농부지기
,

[ Oracle - connect_by_isleaf  ]

 


 

 
정렬 을 위한 것 에서 사용 될때 마지막 레벨 에 해당 되는 녀석들 만 
조회 값이 '1' 로 조회할수 있게 하는 기능 이다. 
예를 들어 보자 
 
1
    2 -- leaf 에 해당되는 녀석
    3 -- leaf 에 해당되는 녀석
4
   5
       6 -- leaf 에 해당되는 녀석
       7 -- leaf 에 해당되는 녀석
8
   9
       10 -- leaf 에 해당되는 녀석

이런식으로 레벨 별로 디비에 저장 되어 있다고 하자 .
2,3,6,7,10 은 leaf 에 해당된다. 이녀석들은 조회시 
connect_by_isleaf 를 사용 해서 '1' 로 조회할수 있다. 그리고 leaf 가 아닌 녀석들은 '0' 으로 조회된다.
그럼 쿼리 를 만들어 보자 

select NUMBER
      ,CONNECT_BY_ISLEAF AS LEAF
 from NUMBER_ALL
 start with HI_NUMBER is null
 connect by prior NUMBER = HI_NUMBER

그럼 결과는 
NUMBER LEAF
1   0
2   1
3   1
4   0
5   0
6   1
7   1
8   0
9    0
10   1 

이런식으로 connect_by_isleaf 를 사용 하면 레벨 에 상관없이 마지막 하위 레벨의 number 들만 따로 조회 할수 있다. 

 

'(DB) Oracle > SQL.통계-Connect by' 카테고리의 다른 글

Oracle - wm_concat  (0) 2017.01.21
Oracle - Connect_By  (0) 2017.01.21
Posted by 농부지기
,