ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [PL/SQL] 레코드 (Record)
    IT, 프로그래밍/Database (Oracle) 2019. 1. 18. 13:02


    레코드 (Record) : 레코드란 여러 가지 데이터 타입을 가질 수 있는 복합형 구조의 데이터 타입이며, 하나의 행(Row)에 대응한다. 


    C언어에서 구조체(struct)와 유사한 개념이다.


    레코드는 선언 방식에 따라 커서형, 사용자 정의형, 테이블형 레코드로 나눌 수 있다.



    1. 사용자 정의형 레코드


    TYPE 레코드명 IS RECORD (

    필드명1 필드1 타입[ [NOT NULL] := 디폴트값 ],

    필드명2 필드2 타입[ [NOT NULL] := 디폴트값 ] ... );

    레코드변수명 레코드명;



    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    DECLARE
        TYPE dept_rect IS RECORD(
          department_id NUMBER := 1,  --혹은 departments.department_id%TYPE
          department_name VARCHAR2(80),  --혹은 departments.department_name%TYPE
          parent_id NUMBER(6),
          manager_id NUMBER(6));
          
        vr_dept_rect dept_rect;
        
     BEGIN
        
        DBMS_OUTPUT.PUT_LINE(vr_dept_rect.department_id);
        
     END;
    cs


    선언한 레코드 변수를 통해 내부의 속성들에 접근할 수 있다.



    2. 테이블형 레코드


    레코드 변수명 테이블명.%ROWTYPE;



    1
    2
    3
    4
    5
    6
    7
     DECLARE
        vr_dept_rect departments%ROWTYPE;
        
        BEGIN
          SELECT * into vr_dept_rect from departments where department_id = 10;
         DBMS_OUTPUT.PUT_LINE(vr_dept_rect.department_id);    

    END;
    cs



    특정 테이블의 모든 컬럼을 받을때 사용하는 레코드 타입이다. %TYPE 대신 %ROWTYPE으로 선언함.



    3. 커서형 레코드


    커서를 레코드 변수로 받는 것. ( >> 커서에 관한 건 여기를 참고 << )


    커서명%ROWTYPE



    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    DECLARE
        CURSOR cur_dep IS
            SELECT * from departments;
        vr_dep cur_dep%ROWTYPE;
        
        BEGIN
        OPEN cur_dep;
        
        LOOP
          FETCH cur_dep INTO vr_dep;
          
          EXIT WHEN cur_dep%NOTFOUND;
          
        

          DBMS_OUTPUT.PUT_LINE(vr_dep.department_id);
          DBMS_OUTPUT.PUT_LINE(vr_dep.department_name);
     
        END LOOP;
        
          DBMS_OUTPUT.PUT_LINE(cur_dep%ROWCOUNT);
          --DBMS_OUTPUT.PUT_LINE(vr_dep%ROWCOUNT);
        END;
    cs




    vr_dep 변수로 현재 커서가 가리키고 있는 집합 속의 행들을 출력하는 것을 볼 수 있다.

    유의할점은 vr_dep는 커서는 아니라는 점이다. 주석처리 된 부분을 실행시켜보면 커서가 아니라는 오류를 뱉어내며 컴파일 에러를 일으킨다.


    4. 중첩 레코드

    레코드 안에서, 다른 레코드를 선언하여 사용하는 것.
    레코드의 필드 타입이 레코드인 것임.


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    DECLARE
      
      TYPE dep_rec IS RECORD(
          dep_id DEPARTMENTS.DEPARTMENT_ID%TYPE,
          dep_name DEPARTMENTS.DEPARTMENT_NAME%TYPE );
        
      TYPE emp_rec IS RECORD(
          emp_id EMPLOYEES.EMPLOYEE_ID%TYPE,
          emp_name EMPLOYEES.EMP_NAME%TYPE,
          dep dep_rec);
        
          vr_emp_id EMPLOYEES.EMPLOYEE_ID%TYPE;
          vr_emp_name EMPLOYEES.EMP_NAME%TYPE;
          vr_dep_id DEPARTMENTS.DEPARTMENT_ID%TYPE;
          vr_dep_name DEPARTMENTS.DEPARTMENT_NAME%TYPE;
          vr_emp_rec emp_rec;
     
    BEGIN
     
          SELECT a.emp_name, a.employee_id, a.department_id, b.department_name
          INTO vr_emp_rec.emp_name, vr_emp_rec.emp_id, vr_emp_rec.dep.dep_idvr_emp_rec.dep.dep_name
          FROM employees a, departments b
          WHERE a.employee_id = 100
          AND a.department_id = b.department_id;
      
          DBMS_OUTPUT.PUT_LINE('emp_id .. ' || vr_emp_rec.emp_id );
          DBMS_OUTPUT.PUT_LINE('emp_name .. ' || vr_emp_rec.emp_name );
          DBMS_OUTPUT.PUT_LINE('dep_id .. ' || vr_emp_rec.dep.dep_id );
          DBMS_OUTPUT.PUT_LINE('dep_name .. ' || vr_emp_rec.dep.dep_name );
     
     
    END;
     
     
    cs


    그림으로 나타내면 아래 구조와 같다.




    타 언어와 비교하자면 C에서는 구조체 안의 구조체 변수, 
    자바에서는 구성관계로 클래스 안에 있는 클래스 변수 등으로 할 수 있겠다.


Designed by Tistory.