Oracle PL/SQL 객체 유형: CREATE TYPE 예제
⚡ 스마트 요약
PL/SQL의 객체 유형은 객체 지향 프로그래밍을 가능하게 합니다. Oracle이를 통해 속성과 메서드를 사용하여 실제 세계의 개체를 모델링할 수 있습니다. 생성자, 상속 및 동등 비교를 지원하므로 단일 스키마 수준 유형으로 구조화된 데이터를 저장하고 처리할 수 있습니다.

PL/SQL의 객체 유형이란 무엇입니까?
객체 지향 프로그래밍은 재사용 가능한 구성 요소와 복잡한 애플리케이션을 구축하는 데 특히 적합합니다. 프로그램은 "액션"이 아닌 "객체"를 중심으로 구성됩니다. 즉, 단일 액션이 아닌 전체 객체와 상호 작용하도록 설계됩니다. 이러한 접근 방식을 통해 프로그래머는 객체 엔티티 수준에서 세부 정보를 입력하고 조작할 수 있습니다.
아래 그림은 은행 계좌를 객체 엔티티로 취급하는 객체 유형의 예를 보여줍니다. 객체 속성은 값을 저장하는데, 은행 계좌의 경우 계좌 번호, 잔액 등이 이에 해당합니다. 객체 메서드는 이자율 계산이나 은행 거래 명세서 생성과 같은 작업을 설명하며, 각 작업은 완료 과정을 필요로 합니다.
In PL / SQL객체 지향 프로그래밍은 객체 유형을 기반으로 합니다. 객체 유형은 현실 세계의 모든 실체를 나타낼 수 있습니다. 아래 섹션에서는 객체 유형, 구성 요소, 그리고 객체 유형을 생성하고 사용하는 방법을 살펴봅니다.
객체 유형의 구성 요소
PL/SQL 객체 유형은 주로 두 가지 구성 요소로 이루어져 있습니다.
- Attributes
- 멤버/메서드
Attributes
속성은 데이터가 저장되는 열 또는 필드입니다. 각 속성은 해당 속성에 대한 처리 및 저장 유형을 정의하는 데이터 형식에 매핑됩니다. 속성은 모든 유효한 형식을 가질 수 있습니다. PL/SQL 데이터 유형, 또는 다른 개체 유형일 수 있습니다.
멤버/메서드
구성원 또는 방법은 다음과 같습니다. 하위 프로그램 객체 타입 내부에 정의되는 멤버입니다. 데이터를 저장하는 데 사용되지 않고, 대신 객체 타입 내부에서 수행되는 처리 과정을 정의합니다. 예를 들어, 객체를 채우기 전에 데이터를 검증하는 기능 등이 있습니다. 멤버는 객체 타입 명세에 선언되고 객체 타입 본문에 정의됩니다. 본문은 선택 사항이며, 멤버가 없는 경우 객체 타입은 본문 부분을 갖지 않습니다.
개체 생성 위치 Oracle
객체 유형은 서브프로그램 수준에서 생성할 수 없으며, 스키마 수준에서만 생성할 수 있습니다. 객체 유형이 스키마에 정의되면 서브프로그램에서 사용할 수 있습니다. 객체 유형은 "CREATE TYPE" 문을 사용하여 생성하며, 유형 본문은 해당 객체 유형이 생성된 후에만 생성할 수 있습니다.
아래 스크린샷은 객체 명세를 위한 CREATE TYPE 구문과 해당 객체의 메서드를 정의하는 CREATE TYPE BODY 구문을 보여줍니다.
CREATE TYPE<object_type_name> AS OBJECT ( <attribute_l><datatype>, . . ); / CREATE TYPE BODY<object_type_name> AS OBJECT ( MEMBER[PROCEDURE|FUNCTION]<member_name> IS <declarative section> BEGIN <execution part> END; . . ); /
구문 설명:
- 위의 구문은 속성을 가진 OBJECT와 메서드를 가진 OBJECT BODY를 생성하는 방법을 보여줍니다.
- 메서드는 개체 본문에 오버로드될 수도 있습니다.
객체 유형의 선언 초기화
PL/SQL의 다른 구성 요소와 마찬가지로 객체 유형은 프로그램에서 사용하기 전에 선언해야 합니다. 객체 유형이 생성되면 하위 프로그램의 선언 섹션에서 해당 객체 유형의 변수를 선언하는 데 사용할 수 있습니다.
변수가 객체 유형으로 선언될 때마다, 런타임에 해당 객체 유형의 새 인스턴스가 생성되고, 이 새로 생성된 인스턴스가 변수 이름으로 참조됩니다. 이러한 방식으로 하나의 객체 유형이 여러 인스턴스에 걸쳐 여러 값을 저장할 수 있습니다.
아래 스크린샷은 변수가 객체 유형으로 선언된 것을 보여줍니다. PL/SQL 블록.
DECLARE <variable_name> <object_type_name>; BEGIN . . END; /
구문 설명:
- 위의 구문은 a의 선언을 보여줍니다. 변수 선언 섹션에서 객체 유형으로 사용됩니다.
서브프로그램에서 변수가 객체 유형으로 선언되면, 해당 변수는 원자적으로 null이 됩니다. 즉, 객체 자체가 null입니다. 프로그램에서 사용하기 전에 반드시 값을 할당하여 초기화해야 합니다. 객체는 생성자를 사용하여 초기화됩니다.
생성자는 객체의 암묵적인 메서드로, 객체 유형과 동일한 이름으로 참조할 수 있습니다. 아래 스크린샷은 객체 유형 인스턴스의 초기화 과정을 보여줍니다.
DECLARE <variable_name> <object_type_name>; BEGIN <variable_name>:=<object_type_name>(); END; /
구문 설명:
- 위 구문은 객체 유형 인스턴스를 null 값으로 초기화하는 방법을 보여줍니다.
- 객체 자체는 초기화되면 더 이상 null이 아니지만, 객체 내부의 속성들은 값이 할당될 때까지 null 상태로 유지됩니다.
생성자
생성자는 객체의 암묵적인 메서드로, 객체의 타입과 동일한 이름으로 참조할 수 있습니다. 객체가 처음 참조될 때마다 이 생성자가 암묵적으로 호출됩니다.
이러한 생성자를 사용하여 객체를 초기화할 수도 있습니다. 생성자는 객체 유형 본문에 객체 유형과 동일한 이름을 가진 멤버를 정의함으로써 명시적으로 정의할 수 있습니다.
예 1 : 다음 예제에서는 객체 유형 멤버를 사용하여 emp 테이블에 ('RRR', 1005, 20000, 1000) 및 ('PPP', 1006, 20000, 1001) 값을 가진 레코드를 삽입합니다. 데이터가 삽입되면 객체 유형 멤버를 사용하여 결과를 표시합니다. 또한 명시적 생성자를 사용하여 두 번째 레코드의 관리자 ID를 기본값인 1001로 채웁니다.
우리는 다음 단계에 따라 실행합니다.
- 1단계: 객체 유형과 객체 유형 본문을 생성합니다.
- 2단계: emp_no 1005에 대한 암시적 생성자를 통해 객체 유형을 호출하는 익명 블록을 생성합니다.
- 3단계: emp_no 1006에 대한 명시적 생성자를 통해 객체 유형을 호출하는 익명 블록을 생성합니다.
1단계) 객체 유형과 객체 유형 본문을 생성합니다.
아래 스크린샷은 emp_object 객체 유형 명세가 속성 및 멤버와 함께 생성되는 과정을 보여줍니다.
CREATE TYPE emp_object AS OBJECT( emp_no NUMBER, emp_name VARCHAR2(50), salary NUMBER, manager NUMBER, CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER, p_emp_name VARCHAR2, p_salary NUMBER) RETURN SELF AS RESULT), MEMBER PROCEDURE insert_records, MEMBER PROCEDURE display_records); /
아래 스크린샷은 명시적 생성자와 멤버 프로시저를 사용하여 emp_object 형식의 본문이 생성되는 것을 보여줍니다.
CREATE OR REPLACE TYPE BODY emp_object AS CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER,p_emp_name VARCHAR2, p_salary NUMBER) RETURN SELF AS RESULT IS BEGIN Dbms_output.put_line('Constructor fired..'); SELF.emp_no:=p_emp_no; SELF.emp_name:=p_emp_name; SELF.salary:=p_salary; SELF.manager:=1001; RETURN; END; MEMBER PROCEDURE insert_records IS BEGIN INSERT INTO emp VALUES(emp_no,emp_name,salary,manager); END; MEMBER PROCEDURE display_records IS BEGIN Dbms_output.put_line('Employee Name:'||emp_name); Dbms_output.put_line('Employee Number:'||emp_no); Dbms_output.put_line('Salary:'||salary); Dbms_output.put_line('Manager:'||manager); END; END; /
Code 설명
- Code 1-9행: 4개의 속성과 3개의 멤버를 가진 'emp_object' 객체 타입을 생성합니다. 이 객체 타입에는 매개변수가 3개뿐인 생성자 정의가 포함되어 있습니다. (실제 암시적 생성자는 객체 타입에 있는 속성 개수와 동일한 개수의 매개변수를 가집니다.)
- Code 10행: 본문을 생성하는 중입니다.
- Code 11-21행: 명시적 생성자를 정의합니다. 매개변수 값을 속성에 할당하고 'manager' 속성에 기본값 '1001'을 할당합니다.
- Code 22-26행: 'insert_records' 멤버를 정의하면, 해당 멤버의 속성 값이 'emp' 테이블에 삽입됩니다.
- Code 27-34행: 객체 유형 속성 값을 표시하는 멤버 'display_records'를 정의합니다.
출력:
생성된 유형
유형 본문이 생성되었습니다.
단계 2) emp_no 1005에 대한 암시적 생성자를 통해 생성된 객체 유형을 호출하기 위한 익명 블록을 생성합니다.
아래 스크린샷은 암시적 생성자를 통해 emp_object를 호출하는 익명 코드 블록을 보여줍니다.
DECLARE guru_emp_det emp_object; BEGIN guru_emp_det:=emp_object(1005,'RRR',20000,1000); guru_emp_det.display_records; guru_emp_det.insert_records; COMMIT; END;
Code 설명
- Code 37-45행: 암시적 생성자를 사용하여 레코드를 삽입합니다. 생성자 호출에는 속성 값의 실제 개수가 포함됩니다.
- Code 38행: 'guru_emp_det'를 'emp_object' 객체 유형으로 선언합니다.
- Code 41행: 'guru_emp_det.display_records' 문은 'display_records' 멤버를 호출하고 속성 값을 표시합니다.
- Code 42행: 'guru_emp_det.insert_records' 문은 'insert_records' 멤버를 호출하고 속성 값을 테이블에 삽입합니다. 그런 다음 블록이 커밋합니다. 거래.
출력:
직원 이름: RRR
직원 번호: 1005
급여: 20000
관리자 : 1000
단계 3) emp_no 1006에 대한 명시적 생성자를 통해 생성된 객체 유형을 호출하기 위한 익명 블록을 생성합니다.
아래 스크린샷은 세 개의 인수를 사용하여 명시적 생성자를 통해 emp_object를 호출하는 익명 코드 블록을 보여줍니다.
DECLARE guru_emp_det emp_object; BEGIN guru_emp_det:=emp_object(1006,'PPP',20000); guru_emp_det.display_records; guru_emp_det.insert_records; COMMIT; END; /
산출
Employee Name:PPP Employee Number:1006 Salary:20000 Manager:1001
Code 설명 :
- Code 46-53행: 명시적 생성자를 사용하여 레코드를 삽입합니다.
- Code 46행: 'guru_emp_det'를 'emp_object' 객체 유형으로 선언합니다.
- Code 50행: 'guru_emp_det.display_records' 문은 'display_records' 멤버를 호출하고 속성 값을 표시합니다.
- Code 51행: 'guru_emp_det.insert_records' 문은 'insert_records' 멤버를 호출하고 속성 값을 테이블에 삽입합니다. 세 개의 인수만 전달되므로 명시적 생성자는 관리자 ID를 기본값인 1001로 설정합니다.
객체 유형의 상속
상속 속성을 사용하면 하위 객체 유형이 상위 객체 유형, 즉 부모 객체 유형의 모든 속성과 멤버에 접근할 수 있습니다.
하위 객체 유형을 상속된 객체 유형이라고 하고, 상위 객체 유형을 부모 객체 유형이라고 합니다. 아래 구문은 부모 및 상속된 객체 유형을 생성하는 방법을 보여줍니다. 아래 스크린샷은 부모(SUPER) 유형 구문을 NOT FINAL로 표시한 것입니다.
CREATE TYPE <object_type_name_parent> AS OBJECT ( <attribute_l><datatype>, . . )NOT FINAL; /
구문 설명:
- 위 구문은 SUPER 타입을 생성하는 방법을 보여줍니다. NOT FINAL 절을 사용하면 해당 타입을 상속할 수 있습니다.
아래 스크린샷은 UNDER 키워드를 사용하여 생성된 상속된(SUB) 유형 구문을 보여줍니다.
CREATE TYPE<object_type_name_sub>UNDER<object_type_name_parent> ( <attribute_l><datatype>, . ); /
구문 설명:
- 위 구문은 SUB 타입의 생성 방법을 보여줍니다. SUB 타입은 부모 객체 타입의 모든 멤버와 속성을 포함합니다.
예 1 : 아래 예시에서는 상속 속성을 사용하여 관리자 ID가 '1002'인 레코드를 ('RRR', 1007, 20000)에 삽입합니다. 프로그램은 다음 단계에 따라 실행됩니다.
- 1단계: SUPER 유형을 생성합니다.
- 2단계: SUB 유형과 본문을 생성합니다.
- 3단계: SUB 형식을 호출하는 익명 블록을 생성합니다.
1단계) 상위 유형 또는 부모 유형을 생성합니다.
아래 스크린샷은 NOT FINAL 절을 사용하여 emp_object 슈퍼 타입이 생성되는 것을 보여줍니다.
CREATE TYPE emp_object AS OBJECT( emp_no NUMBER, emp_name VARCHAR2(50), salary NUMBER, manager NUMBER, CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER,p_emp_name VARCHAR2(50), p_salary NUMBER)RETURN SELF AS RESULT), MEMBER PROCEDURE insert_records, MEMBER PROCEDURE display_records)NOT FINAL; /
Code 설명 :
- Code 1-9행: 4개의 속성과 3개의 멤버를 가진 'emp_object' 객체 타입을 생성합니다. 이 타입에는 매개변수가 3개뿐인 생성자 정의가 포함되어 있습니다. 'NOT FINAL'로 선언되었으므로 부모 타입입니다.
2단계) SUPER 유형 아래에 SUB 유형을 생성합니다.
아래 스크린샷은 sub_emp_object 상속 유형과 해당 본문이 생성되는 과정을 보여줍니다.
CREATE OR REPLACE TYPE sub_emp_object UNDER emp_object (default_manager NUMBER,MEMBER PROCEDURE insert_default_mgr); / CREATE OR REPLACE TYPE BODY sub_emp_object AS MEMBER PROCEDURE insert_default_mgr IS BEGIN INSERT INTO emp VALUES(emp_no,emp_name,salary,manager); END; END; /
Code 설명 :
- Code 10-13행: 'sub_emp_object'를 상속받은 타입으로 생성하고, 'default_manager'라는 추가 속성과 멤버 프로시저 선언을 추가합니다.
- Code 14행: 상속된 객체 유형의 본문을 생성합니다.
- Code 16-21행: 관리자 값을 제외하고 SUPER 객체 유형의 값을 사용하여 'emp' 테이블에 레코드를 삽입하는 멤버 프로시저를 정의합니다. 관리자 값으로는 SUB 유형의 'default_manager'를 사용합니다.
3단계) SUB 타입을 호출하는 익명 블록을 생성합니다.
아래 스크린샷은 SUB 타입을 호출하고 기본 관리자 ID를 삽입하는 익명 블록을 보여줍니다.
DECLARE guru_emp_det sub_emp_object; BEGIN guru_emp_det:= sub_emp_object(1007,'RRR',20000,1000,1002); guru_emp_det.insert_default_mgr; COMMIT; END; /
Code 설명 :
- Code 25행: 'guru_emp_det'을 'sub_emp_object' 유형으로 선언합니다.
- Code 27행: 암시적 생성자를 사용하여 객체를 초기화합니다. 생성자는 5개의 매개변수(PARENT 유형의 속성 4개와 SUB 유형의 속성 1개)를 갖습니다. 마지막 매개변수(1002)는 default_manager 속성의 값을 정의합니다.
- Code 28행: 생성자에 전달된 기본 관리자 ID를 사용하여 레코드를 삽입하려면 'insert_default_mgr' 멤버를 호출합니다.
PL/SQL 객체의 동등성
같은 객체 유형에 속하는 객체 인스턴스는 동등성을 비교할 수 있습니다. 이를 위해서는 객체 유형에 ORDER 메서드라는 특별한 메서드가 필요합니다.
이 ORDER 메서드는 숫자형 값을 반환하는 함수여야 합니다. 입력으로 두 개의 매개변수를 받습니다(첫 번째 매개변수: 자기 자신 객체 인스턴스의 ID, 두 번째 매개변수: 다른 객체 인스턴스의 ID).
두 객체 인스턴스의 ID를 비교하고, 그 결과를 숫자로 반환합니다.
- 양수 값은 SELF 객체 인스턴스가 다른 인스턴스보다 크다는 것을 나타냅니다.
- 음수 값은 SELF 객체 인스턴스가 다른 인스턴스보다 작다는 것을 나타냅니다.
- 0은 SELF 객체 인스턴스가 다른 인스턴스와 동일함을 나타냅니다.
- 두 인스턴스 중 하나라도 null이면 함수는 null을 반환합니다.
아래 스크린샷은 동등성 검사를 위해 형식 본문에 포함되어야 하는 ORDER 멤버 함수 구문을 보여줍니다.
CREATE TYPE BODY<object_type_name_ 1>AS OBJECT ( ORDER MEMBER FUNCTION match(<parameter> object_type_name_ 1) RETURN INTEGER IS BEGIN IF <attribute_name>parameter <attribute_name>THEN RETURN -1; --any negative number will do ELSIF id>c.id THEN RETURN 1; --any positive number will do ELSE RETURN 0; END IF; END; . . ); /
구문 설명:
- 위 구문은 동등성 검사를 위해 형식 본문에 포함되어야 하는 ORDER 함수를 보여줍니다.
- 이 함수의 매개변수는 동일한 객체 유형의 인스턴스여야 합니다.
- 이 함수는 "obj_instance_1.match(obj_instance_2)"와 같이 호출할 수 있으며, 이 표현식은 표시된 숫자 값을 반환합니다. 여기서 obj_instance_1과 obj_instance_2는 객체 유형의 인스턴스입니다.
예 1 : 다음 예제에서는 두 객체를 비교합니다. 두 개의 인스턴스를 생성하고 두 인스턴스 간의 '급여' 속성을 비교합니다. 이 과정은 두 단계로 진행됩니다.
- 1단계: 객체 유형과 본문을 생성합니다.
- 2단계: 객체 인스턴스를 비교하기 위한 익명 블록을 생성합니다.
1단계) 객체 유형 및 본문 생성.
아래 스크린샷은 emp_object_equality 명세와 그 본문을 보여줍니다. 본문에는 급여 속성을 비교하는 ORDER 함수가 정의되어 있습니다.
CREATE TYPE emp_object_equality AS OBJECT( salary NUMBER, ORDER MEMBER FUNCTION equals(c emp_object_equality)RETURN INTEGER); /
CREATE TYPE BODY emp_object_equality AS ORDER MEMBER FUNCTION equals(c emp_object_equality)RETURN INTEGER IS BEGIN IF salary<c.salary THEN RETURN -1; ELSIF salary>c.salary THEN RETURN 1; ELSE RETURN 0; END IF; END; END; /
Code 설명 :
- Code 1-4행: 속성 1개와 멤버 1개를 가진 'emp_object_equality' 객체 유형을 생성합니다.
- Code 6-16행: SELF 인스턴스와 매개변수 인스턴스의 'salary' 속성을 비교하는 ORDER 함수를 정의합니다. SELF의 급여가 매개변수 인스턴스의 급여보다 작으면 음수 값을, 크면 양수 값을, 같으면 0을 반환합니다.
Code 출력:
생성된 유형
2단계) 객체 인스턴스를 비교하기 위한 익명 블록을 생성합니다.
아래 스크린샷은 급여를 기준으로 두 emp_object_equality 인스턴스를 비교하는 익명 블록을 보여줍니다.
DECLARE l_obj_1 emp_object_equality; l_obj_2 emp_object_equality; BEGIN l_obj_1:=emp_object_equality(15000); l_obj_2:=emp_object_equality(17000); IF l_obj_1.equals(l_obj_2)>0 THEN Dbms_output.put_line('Salary of first instance is greater'); ELSIF l_obj_1.equals(l_obj_2)<0 THEN Dbms_output.put_line('Salary of second instance is greater'); ELSE Dbms_output.put_line('Salaries are equal'); END IF; END; /
산출
Salary of second instance is greater
Code 설명 :
- Code 20행: 'emp_object_equality' 유형의 'l_obj_1'를 선언합니다.
- Code 21행: 'emp_object_equality' 유형의 'l_obj_2'를 선언합니다.
- Code 23행: 'l_obj_1'를 급여 값 '15000'으로 초기화합니다.
- Code 24행: 'l_obj_2'를 급여 값 '17000'으로 초기화합니다.
- Code 25-33행: ORDER 함수가 반환한 숫자에 따라 메시지를 출력합니다.


















