Oracle 예제가 포함된 PL/SQL 객체 유형 튜토리얼
PL/SQL의 객체 유형이란 무엇입니까?
객체 지향 프로그래밍은 특히 재사용 가능한 구성 요소와 복잡한 애플리케이션을 구축하는 데 적합합니다. 이들은 "작업"보다는 "객체"를 중심으로 구성됩니다. 즉, 프로그램은 단일 작업보다는 전체 객체와 작동하고 상호 작용하도록 설계되었습니다. 이 개념을 통해 프로그래머는 객체 엔터티 수준에서 세부 정보를 채우고 조작할 수 있습니다.
아래 그림은 은행 계좌가 객체 엔터티로 간주되는 객체 유형의 예를 보여줍니다. 객체 속성에는 은행 계좌와 같이 일부 속성 값을 보유하는 항목이 포함됩니다. 계좌 번호, 은행 잔고 등입니다. 객체 메서드는 이자율 계산, 은행 명세서 생성 등과 같은 특정 프로세스를 완료해야 하는 항목을 설명합니다.
PL/SQL에서 객체 지향 프로그래밍은 객체 유형을 기반으로 합니다.
객체 유형은 실제 엔터티를 나타낼 수 있습니다. 이 장에서는 더 많은 객체 유형에 대해 논의할 것입니다.
객체 유형의 구성 요소
PL / SQL 객체 유형에는 주로 두 가지 구성 요소가 포함됩니다.
- Attributes
- 멤버/메서드
Attributes
속성은 데이터가 저장되는 열 또는 필드입니다. 각 속성은 해당 속성에 대한 처리 및 저장 유형을 정의하는 데이터 유형에 매핑됩니다. 속성은 무엇이든 유효할 수 있습니다. PL/SQL 데이터 유형, 또는 다른 개체 유형일 수 있습니다.
멤버/메서드
멤버 또는 메소드는 객체 유형에 정의된 하위 프로그램입니다. 데이터를 저장하는 데 사용되지 않습니다. 주로 객체 유형 내부의 프로세스를 정의하는 데 사용됩니다. 예를 들어 객체 유형을 채우기 전에 데이터 유효성을 검사합니다. 이는 객체 유형 섹션에서 선언되고 객체 유형의 객체 유형 본문 섹션에서 정의됩니다. 객체형의 Body 부분은 선택적인 부분입니다. 멤버가 없으면 개체 유형에 본문 부분이 포함되지 않습니다.
개체 생성 위치 Oracle
개체 유형은 하위 프로그램 수준에서 생성할 수 없으며 스키마 수준에서만 생성할 수 있습니다. 객체 유형이 스키마에 정의되면 하위 프로그램에서도 동일한 객체 유형을 사용할 수 있습니다. 'CREATE TYPE'을 이용하여 객체 타입을 생성할 수 있다. 유형 본문은 객체 유형을 생성한 후에만 생성할 수 있습니다.
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의 다른 구성 요소와 마찬가지로 객체 유형도 프로그램에서 사용하기 전에 선언해야 합니다.
객체 유형이 생성되면 서브프로그램 선언 섹션에서 해당 객체 유형의 변수를 선언하는 데 사용할 수 있습니다.
하위 프로그램에서 변수가 객체 유형으로 선언될 때마다 런타임 시 해당 객체 유형의 새 인스턴스가 생성되고 새로 생성된 이 인스턴스를 변수 이름으로 참조할 수 있습니다. 이러한 방식으로 단일 개체 유형은 여러 인스턴스에 여러 값을 저장할 수 있습니다.
DECLARE <variable_name> <object_type_name>; BEGIN . . END; /
구문 설명:
- 위 구문은 선언 섹션에서 변수를 객체 유형으로 선언하는 것을 보여줍니다.
변수가 서브프로그램에서 객체 유형으로 선언되면 원자적으로 null이 됩니다. 즉, 전체 객체 자체가 null이 됩니다. 프로그램에서 사용하려면 값으로 초기화해야 합니다. 생성자를 사용하여 초기화할 수 있습니다.
생성자는 객체 유형과 동일한 이름으로 참조될 수 있는 객체의 암시적 메서드입니다. 아래 구문은 객체 유형의 초기화를 보여줍니다.
DECLARE <variable_name> <object_type_name>; BEGIN <variable_name>:=<object_type_name>(); END; /
구문 설명:
- 위 구문은 null 값을 사용한 객체 유형 인스턴스의 초기화를 보여줍니다.
- 이제 개체 자체는 초기화되었으므로 null이 아니지만 개체 내부의 속성은 이러한 속성에 값을 할당하지 않았으므로 null이 됩니다.
생성자
생성자는 객체 유형과 동일한 이름으로 참조될 수 있는 객체의 암시적 메서드입니다. 객체가 처음 참조될 때마다 이 생성자가 암시적으로 호출됩니다.
또한 이러한 생성자를 사용하여 객체를 초기화할 수도 있습니다. 생성자는 객체 유형과 동일한 이름을 가진 객체 유형 body에 멤버를 정의하여 명시적으로 정의할 수 있습니다.
예제 1: 다음 예제에서는 개체 유형 멤버를 사용하여 레코드를 값 ('RRR', 1005, 20000, 1000) 및 ('PPP', 1006, 20000, 1001)로 emp 테이블에 삽입합니다. 데이터가 삽입되면 개체 유형 멤버를 사용하여 동일한 데이터를 표시합니다. 또한 명시적 생성자를 사용하여 두 번째 레코드에 대해 기본적으로 관리자 ID를 1001 값으로 채웁니다.
아래 단계에 따라 실행하겠습니다.
- Step1 :
- 객체 유형 생성
- 객체 유형 본체
- 2단계: emp_no 1005에 대한 암시적 생성자를 통해 생성된 객체 유형을 호출하기 위한 익명 블록 생성.
- 3단계: emp_no 1006에 대한 명시적 생성자를 통해 생성된 객체 유형을 호출하기 위한 익명 블록 생성.
단계 1) 객체 유형 및 객체 유형 본문 생성
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); /
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.managerial:=1001; RETURN; END: MEMBER PROCEDURE insert_records IS BEGIN INSERT INTO emp VALUES(emp_noemp_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: /
코드 설명
- 코드 라인 1-9: 4개의 속성과 3개의 멤버로 'emp_object' 객체 유형을 생성합니다. 여기에는 매개변수가 3개만 있는 생성자의 정의가 포함되어 있습니다. (실제 암시적 생성자는 객체 유형에 존재하는 속성 수와 동일한 수의 매개변수를 포함합니다.)
- 코드 라인 10: 타입 바디를 생성합니다.
- 코드 라인 11-21: 명시적 생성자를 정의합니다. 매개변수 값을 속성에 할당하고 'manager' 속성에 기본값 '1001'을 할당합니다.
- 코드 라인 22-26: 'emp' 테이블에 속성 값이 삽입되는 'insert_records' 멤버를 정의합니다.
- 코드 라인 27-34: 객체 유형 속성의 값을 표시하는 'display_records' 멤버를 정의합니다.
산출
생성된 유형
유형 본문이 생성되었습니다.
단계 2) emp_no 1005에 대한 암시적 생성자를 통해 생성된 객체 유형을 호출하기 위한 익명 블록 생성
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;
코드 설명
- 코드 라인 37-45: 암시적 생성자를 사용하여 레코드를 삽입합니다. 생성자 호출에는 실제 속성 값 수가 포함됩니다.
- 코드 라인 38: guru_emp_det를 'emp_object'의 객체 유형으로 선언합니다.
- 코드 라인 41: 'guru_emp_det.display_records' 문장은 'diplay_records' 멤버 함수를 호출하고 속성 값이 표시됩니다.
- 코드 라인 42: 'insert_records' 멤버 함수를 호출한 'guru_emp_det.insert_records' 문과 속성 값이 테이블에 삽입됩니다.
산출
직원 이름: RRR
직원 번호: 1005
급여: 20000
관리자 : 1000
단계 3) emp_no 1006에 대한 명시적 생성자를 통해 생성된 객체 유형을 호출하기 위한 익명 블록 생성
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
코드 설명 :
- 코드 라인 46-53: 명시적 생성자를 사용하여 레코드를 삽입합니다.
- 코드 라인 46: guru_emp_det를 'emp_object'의 객체 유형으로 선언합니다.
- 코드 라인 50: 'guru_emp_det.display_records' 문장은 'display_records' 멤버 함수를 호출하고 속성 값이 표시됩니다.
- 코드 라인 51: 'insert_records' 멤버 함수를 호출한 'guru_emp_det.insert_records' 문과 속성 값이 테이블에 삽입됩니다.
객체 유형의 상속
상속 속성을 사용하면 하위 개체 유형이 상위 개체 유형 또는 상위 개체 유형의 모든 속성과 멤버에 액세스할 수 있습니다.
하위 개체 유형을 상속된 개체 유형이라고 하며 상위 개체 유형을 상위 개체 유형이라고 합니다. 아래 구문은 상위 및 상속된 개체 유형을 만드는 방법을 보여줍니다.
CREATE TYPE <object_type_name_parent> AS OBJECT ( <attribute_l><datatype>, . . )NOT FINAL; /
구문 설명:
- 위 구문은 SUPER 유형의 생성을 보여줍니다.
CREATE TYPE<object_type_name_sub>UNDER<object_type_name_parent> ( <attribute_l><datatype>, . ); /
구문 설명:
- 위의 구문은 SUB 유형의 생성을 보여줍니다. 여기에는 상위 개체 유형의 모든 멤버와 속성이 포함됩니다.
EXAMPLE1 : 아래 예에서 상속 속성을 사용하여 다음 레코드('RRR', 1002, 1007)에 대해 관리자 ID가 '20000'인 레코드를 삽입합니다.
우리는 다음 단계에서 위의 프로그램을 실행할 것입니다.
- 1단계: SUPER 유형을 생성합니다.
- 2단계: SUB 유형 및 본문을 생성합니다.
- 3단계: SUB 유형을 호출하기 위한 익명 블록 생성.
단계 1) SUPER 유형 또는 상위 유형을 만듭니다.
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; /
코드 설명 :
- 코드 라인 1-9: 4개의 속성과 3개의 멤버로 'emp_object' 객체 유형을 생성합니다. 여기에는 매개변수가 3개만 있는 생성자의 정의가 포함되어 있습니다. 'NOT FINAL'로 선언되었으므로 상위 유형입니다.
단계 2) SUPER 유형 아래에 SUB 유형을 만듭니다.
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; /
코드 설명 :
- 코드 라인 10-13: 'default_manager' 속성 하나와 멤버 프로시저 선언을 추가하여 상속된 유형으로 sub_emp_object를 생성합니다.
- 코드 라인 14: 상속된 객체 유형에 대한 본문을 생성합니다.
- 코드 라인 16-21: 관리자 값을 제외한 'SUPER' 객체 유형의 값으로 "emp" 테이블에 레코드를 삽입하는 멤버 프로시저를 정의합니다. 관리자 값은 'SUB' 유형의 'default_manager'를 사용하고 있습니다.
단계 3) SUB 유형을 호출하기 위한 익명 블록 생성
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; /
코드 설명 :
- 코드 라인 25: 'guru_emp_det'을 'sub_emp_object' 유형으로 선언합니다.
- 코드 라인 27: 암시적 생성자를 사용하여 객체를 초기화합니다. 생성자에는 5개의 매개변수(PARENT 유형의 속성 4개, SUB 유형의 속성 2개)가 있습니다. 마지막 매개변수(1002)는 default_manager 속성의 값을 정의합니다.
- 코드 라인 28: 'insert_default_mgr' 멤버를 호출하여 생성자에 전달된 기본 관리자 ID가 있는 레코드를 삽입합니다.
PL/SQL 객체의 동등성
동일한 개체에 속하는 개체 인스턴스가 동일한지 비교할 수 있습니다. 이를 위해서는 'ORDER' 메소드라는 객체 유형의 특별한 메소드가 필요합니다.
이 'ORDER' 메소드는 숫자형을 반환하는 함수여야 합니다. 두 개의 매개변수를 입력으로 사용합니다(첫 번째 매개변수: 자체 개체 인스턴스의 ID, 두 번째 매개변수: 다른 개체 인스턴스의 ID).
두 객체 인스턴스의 id를 비교하여 그 결과를 숫자로 반환합니다.
- 양수 값은 SELF 개체 인스턴스가 다른 인스턴스보다 크다는 것을 나타냅니다.
- 음수 값은 SELF 개체 인스턴스가 다른 인스턴스보다 작음을 나타냅니다.
- XNUMX은 SELF 개체 인스턴스가 다른 인스턴스와 동일함을 나타냅니다.
- 인스턴스 중 하나라도 null이면 이 함수는 null을 반환합니다.
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는 object_type_name의 인스턴스입니다.
Example1: 다음 예제에서는 두 객체를 비교하는 방법을 살펴보겠습니다. 두 인스턴스를 만들고 두 인스턴스 간의 속성 'salary'를 비교합니다. 두 단계를 거치게 됩니다.
- 1단계: 개체 유형 및 본문 만들기.
- 2단계: 객체 인스턴스를 호출하기 위해 익명 블록을 생성합니다.
단계 1) 객체 유형 및 본문을 생성합니다.
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; /
코드 설명 :
- 코드 라인 1-4: 1개의 속성과 1개의 멤버로 'emp_object_equality' 객체 유형을 생성합니다.
- 코드 라인 6-16: SELF 인스턴스와 매개변수 인스턴스 유형의 '급여' 속성을 비교하는 ORDER 함수를 정의합니다. SELF 급여가 적으면 음수를 반환하고 SELF 급여가 크면 양수를 반환하고 급여가 같으면 0을 반환합니다.
코드 출력:
생성된 유형
단계 2) 객체 인스턴스를 호출하기 위해 익명 블록을 생성합니다.
DECLARE l_obj_l emp_object_equality; l_obj_2 emp_object_equality; BEGIN l_obj_l:=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_l.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
코드 설명 :
- 코드 라인 20: emp_object_equality 유형의 l_obj_1을 선언합니다.
- 코드 라인 21: emp_object_equality 유형의 l_obj_2을 선언합니다.
- 코드 라인 23: 급여 값이 '1'인 l_obj_15000 초기화
- 코드 라인 24: 급여 값이 '1'인 l_obj_17000 초기화
- 코드 라인 25-33: ORDER 함수의 반환 번호를 기반으로 메시지를 인쇄합니다.
제품 개요
이 장에서는 객체 유형과 해당 속성을 살펴보았습니다. 또한 PL/SQL 객체의 생성자, 멤버, 속성, 상속 및 평등에 대해서도 논의했습니다.