Object Type(객체 타입) - 2

    정적 메소드

    정적 메소드는 키워드 STATIC FUNCTION 또는 STATIC PROCEDURE를 사용하여 선언되는 서브프로그램이다.

    정적 메소드는 객체 타입 자체에 대해 실행되며, 특정 인스턴스와는 무관하다. 따라서 정적 메소드는 SELF 매개변수를 가지지 않는다.

    -- 정적 메소드 명세
    CREATE OR REPLACE TYPE person_type AS OBJECT (
    	family_name	VARCHAR2(30),	-- 성
        given_name	VARCHAR2(30),	-- 이름
        address_1	VARCHAR2(30),	-- 기본 주소
        address_2	VARCHAR2(30),	-- 상세 주소
        
        MEMBER	FUNCTION  full_name	RETURN VARCHAR2,	-- 풀 네임 반환 메소드
        STATIC	FUNCTION  is_same_address(a_person1 person_type,	-- STATIC 메소드
        								  a_person2 person_type) RETURN BOOLEAN
      );
    CREATE OR REPLACE TYPE BODY person_type
    IS
    	-- 풀 네임(성 + 이름)을 반환
        MEMBER FUNCTION full_name RETURN VARCHAR2
        IS
        BEGIN
        	RETURN family_name || ' ' || given_name;
        END;
        
        -- STATIC 메소드
        STATIC	FUNCTION is_same_address(a_person1 person_type,
        								 a_person2 person_type) RETURN BOOLEAN
        IS
        BEGIN
          IF a_person1.address_1 = a_person2.address_1 AND
             a_person1.address_2 = a_person2.address_2 THEN
            RETURN TRUE;
         ELSE
         	RETURN FALSE;
         END IF;
       END;
    END;
    -- 정적 메소드의 사용
    DECLARE
    	--STATIC 메소드 예제
        v1 person_type := person_type('홍', '길동', '한양 종로', '32번지');
        v2 person_type := person_type('임', '꺽정', '경기도 철원', '산 75번지');
        v3 person_type := person_type('홍', '의정', '한양 종로', '32번지');
    BEGIN
    	DBMS_OUTPUT.PUT_LINE(v1.full_name || ',' || v2.full_name || ': ' ||
        					CASE WHEN person_type.is_same_address(v1, v2)
                            	 THEN '동일 주소' ELSE '다른 주소' END);
        DBMS_OUTPUT.PUT_LINE(v1.full_name || ',' || v3.full_name || ': ' ||
        					CASE WHEN person_type.is_same_address(v1, v3)
                                 THEN '동일 주소' ELSE '다른 주소' END);
    END;
    /
    홍 길동,임 꺽정; 다른 주소
    홍 길동,홍 의정; 동일 주소

    생성자 메소드

    객체 타입의 새로운 인스턴스를 생성하고 속성들에 초깃값을 할당하여 반환하는 함수이다.

    생성자 메소드는 CONSTRUCTOR FUNCTION 키워드를 사용하여 선언되며 함수의 이름이 객체 타입의 이름과 동일해야 한다. 생성자는 다음의 두 가지 유형으로 나뉜다.

    • 시스템 정의 생성자: 시스템이 모든 객체 타입에 대해 묵시적으로 만들어 주는 생성자로 명시적인 선언 없이도 항상 사용할 수 있다. 생성자 메소드에서 매개변수의 개수와 순서는 객체 타입의 속성 개수/순서와 같다. 앞의 예제들에서 이미 다음과 같이 생성자 메소드 person_type을 사용했는데 이 생성자는 명시적으로 선언되지 않았지만 시스템이 기본적으로 정의해 주므로 항상 사용 가능하다.
    v1 person_type := person_type('홍', '길동', '한양 종로', '32번지');
    • 사용자 정의 생성자: 사용자가 명시적으로 정의한 추가 생성자로 주로 사용자가 생성자 함수에 로직을 추가하거나 속성 중 일부를 생략한 생성자를 정의하는 데 사용된다.
    -- 생성자 메소드 명세
    CREATE OR REPLACE TYPE person_type AS OBJECT(
    	family_name	VARCHAR2(30),	-- 성
        given_name  VARCHAR2(30),	-- 이름
        address_1	VARCHAR2(30),	-- 기본 주소
        address_2	VARCHAR2(30),	-- 상세 주소
        
        MEMBER		FUNCTION	display	RETURN VARCHAR2,	-- 속성을 Display
        CONSTRUCTOR FUNCTION 	person_type(a_family_name	VARCHAR2, a_given_name VARCHAR2) -- 생성자
        	RETURN SELF AS RESULT	-- 객체 타입의 생성자는 반환형이 항상 SELF AS RESULT이다.
       );
    -- 생성자 메소드 본체
    CREATE OR REPLACE TYPE BODY person_type
    IS
    	-- 속성을 Display
        MEMBER FUNCTION display RETURN VARCHAR2
        IS
        BEGIN
          RETURN '성: ' ||family_name||', 이름:'||given_name||
          		 ', 기본 주소:'||address_1||', 상세 주소:'||address_2;
        END;
        
        -- 기본 생성자가 아닌 추가 생성자 정의. 주소 없이 이름만으로 객체를 생성한다.
        CONSTRUCTOR FUNCTION person_type(a_family_name VARCHAR2, a_given_name VARCHAR2)
        	RETURN SELF AS RESULT
        IS
        BEGIN
        	family_name := a_family_name;
            given_name := a_given_name;
            address_1 := NULL;
            address_2 := NULL;
            RETURN;	-- 객체 타입의 생성자는 RETURN문의 반환값이 없다.
       END;
    END;

    위의 예제는 사용자 정의 생성자 메소드의 사용방법을 보여준다, 주의해서 볼 것은 생성자의 반환값이다. 반환형이 특이하게 SELF AS RESULT이다. 사용자 정의 생성자는 항상 SELF AS RESULT를 반환하도록 선언되어야 한다. 본체에서도 특이한 사항이 있는데 생성자 메소드가 함수임에도 불구하고 RETURN문에 반환할 값이 지정되지 않았다.(마치 프로시저의RETURN문과 같다. 반환형 SELF AS RESULT의 의미가 SELF를 반환하겠다는 것이므로 SELF가 생략된다고 보면 된다.

     

    다음은 생성자를 사용해 새로운 로우를 테이블에 INSERT하는 방법을 보여준다. 예제를 위해서 객체 타입의 테이블 tb_person을 생성해야 하는데 첫 번째 CREATE문이 이에 해당된다. 객체 타입을 사용하여 테이블을 생성하기 위해 키워드 OF를 사용했다. 뒤따르는 두 개의 INSERT문 중에서 첫 번째는 시스템 정의 생성자를 사용했고, 두 번째 INSERT문은 사용자 정의 생성자를 사용했다.

    -- 생성자 메소드의 사용
    SCOTT> REM person_type의 객체 테이블 생성
    SCOTT> CREATE TABLE tb_person OF person_type;
    
    SCOTT> REM 시스템 정의 생성자(네 개의 매개변수) 사용
    SCOTT> INSERT INTO tb_person VALUES(person_type('홍', '길동', '종로', '일번지'));
    
    1 개의 로우가 만들어졌습니다.
    
    SCOTT> REM 사용자 정의 생성자(두 개의 매개변수) 사용
    SCOTT> INSERT INTO tb_person VALUES(person_type('임', '꺽정'));
    
    1 개의 로우가 만들어졌습니다.
    
    SCOTT> COL FAMILY_NAME FORMAT A11
    SCOTT> COL GIVEN_NAME FORMAT A10
    SCOTT> COL ADDRESS_1 FORMAT A20
    SCOTT> COL ADDRESS_2 FORMAT A20
    SCOTT> SELECT * FROM TB_PERSON;
    
    FAMILY_NAME	GIVEN_NAME	ADDRESS_1	ADDRESS_2
    ----------  ----------  ---------- ------------
    홍			길동		 종로        일번지
    임		 	꺽정

    생성자는 PL/SQL에서도 유용하게 사용된다. 앞에서 레코드에 대해 설명할 때 레코드는 필드 전체를 한 번에 초기화하는 방법을 제공하지 않는다고 했다. 객체 타입은 이 방법을 제공한다.

    -- PL/SQL에서 생성자 사용
    DECLARE
    	-- 선언부에서 선언과 동시에 생성자를 사용하여 초기화(실제로는 NEW 키워드가 생략된 형태임)
        v1 person_type := person_type('홍', '길동', '종로', '32번지');
        v2 person_type;
        v3 person_type;
    BEGIN
    	-- 실행 중에 생성자를 사용하여 초기화한다. 생성자 호출 시에는 키워드 NEW를 사용한다.
        v2 := NEW person_type('손', '오공', '화과산', '동굴');
        -- NEW는 생략 가능하다.
        v3 :=     person_type('임', '꺽정');
    END;

     

    'DATABASE > SQL, PL-SQL' 카테고리의 다른 글

    객체 타입 - 4  (0) 2021.05.09
    객체 타입- 3  (0) 2021.05.06
    Object Type(객체 타입) - 1  (0) 2021.04.17
    Trigger(트리거)  (0) 2021.04.14
    서브프로그램의 다양한 기능들 - 매개변수  (0) 2021.04.01

    댓글