IT, 프로그래밍/Database (Oracle)

[PL/SQL] 레코드 (Record)

오리@ 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에서는 구조체 안의 구조체 변수, 
자바에서는 구성관계로 클래스 안에 있는 클래스 변수 등으로 할 수 있겠다.