database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
PostgreSQL
Firebird
ㆍOracle
Informix
Sybase
MS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
Oracle Columns 7513 게시물 읽기
 News | Q&A | Columns | Tutorials | Devel | Files | Links
No. 7513
개발자들을 위한 Oracle9i의 신기능
작성자
정재익(advance)
작성일
2001-09-24 10:31
조회수
16,193

원본 출처 : http://www.oracle.com/kr/magazine/archive/21fall/index.html?cover3_1.html

 

개발자들을 위한 Oracle9i의 신기능

 

E-business 시대의 개발자들은 전세계를 대상으로 24시간 지속적으로 서비스를 제공할 수 있는 솔루션을

개발해야 한다. 오라클은 새로운 환경에 처한 개발자들의 요구를 최대한 지원할 수 있는 새로운 기능들을

Oracle9i에서 대폭 보강했다. Oracle9i를 통해 개발자들은 글로벌 애플리케이션을 더욱 쉽고 효율적으로

개발할 수 있을 것이다.

 

| 글 | 한국오라클 DB기술팀 |

 

전세계 고객에게 24시간 서비스 제공을 목표로

 

Java를 기반으로 하는 인터넷 서비스 구축이 대중화되면서 Java VM(Virtual Machine)을

데이타베이스 내부에 탑재하고, 객체지향 기반으로 EJB(Enterprise Java Beans)를 이용하여

애플리케이션의 프리젠테이션과 비즈니스 로직을 분리하여 보다 효율적으로 e-business 구축을 지원하기

위해 Oracle8i라는 인터넷 데이타베이스가 출시된 이후, 각종 인터넷 기반 요소 기술 역시 활성화된 언어와

기술이 있는 반면, 개발자들로부터 외면 당한 인터넷 기반 언어 및 요소기술들도 많다.

 

기업의 비즈니스가 단지 고객만을 대상으로 하는 데에서 벗어나 기업과 기업간의 거래인 B2B로 확대되고,

서비스 지역도 국내 시장을 넘어 일본과 중국 시장, 더 나아가 전 세계 시장으로 확장되고 있다.

Oracle9i에서는 새로운 시장과 고객의 욕구를 충족시킬 수 있는 여러 기능들이 새롭게 추가됨으로써

개발자들은 보다 쉽게 애플리케이션을 개발할 수 있으며, 시장 확대를 위해 이중으로 데이타베이스를 구축할

필요가 없도록 하나의 데이타베이스에서 지역적으로 또는 시간적으로 떨어진 고객들을 위해 24시간 지속적으로

서비스를 제공할 수 있게 되었다.

 

대표적으로 XML 문서 자체를 데이타베이스의 한 열로 저장시켜 XPATH를 이용해 다양하게 검색할 수

있는 방법이나, 전세계 57개 언어, 88 지역 그리고 약 200여 개의 문자세트를 하나의 필드에 저장하여

통합적으로 지원 또는 개발을 가능하게 했다. 이것들을 중심으로 개발자들이 Oracle9i를 기반으로

새롭게 개발할 경우, 프로그램 내부에 추가로 코딩할 필요가 없어진 여러 기능들을 살펴보기로 하자.

 

ANSI/ISO SQL:1999 Standard

 

Oracle9i에서는 ANSI/ISO SQL 1999년의 표준에 부합하는 기능을 제공한다. 가장 대표적인 것으로는

조인, CASE 표현식 및 문장, 스칼라 하위질의와 명시적 디폴트 등을 들 수 있다. Oracle SQL은

ANSI/ISO SQL:1999 표준을 지원하며, 기존의 코드를 수정하지 않고 애플리케이션을 이전할 수 있다.

또한 데이타베이스 내에 ANSI/ISO 표준 기능들을 제공하므로 다른 데이타베이스 제품으로부터 사용자를

유도하는데 용이하다.

 

SQL문에서 CASE를 표현하는 방법은 4가지가 있다. 간단한 CASE 표현식, 검색 CASE 표현식, COALESCE 함수

그리고 NULLIF 함수가 있다. 이 중에서 간단한 CASE 표현식은 Oracle 8.1.7에서 제공되었으며,

나머지 기능들은 Oracle9i에서 제공한다. 또한 CASE 표현식은 PL/SQL에서도 지원되며, 표현식과

문장으로 분류된다.

 

간단한 CASE 표현식

 

이것은 Oracle9i 이전의 서버에서 제공하던 DECODE 문장과 유사하며 주어진 표현식에서 검색을 하거나 값을

치환하는 데 사용될 수 있다. 또 각각의 검색 값에 대해서 반환되는 값을 명시할 수 있으나, 비교 연산자는

허용되지 않는다. EMP 테이블에서 각 사원의 고용일에 대해 근속년수를 구하고 이를 화면에 출력하는

SQL문과 출력 결과는 다음과 같다.

 

SQL> SELECT ename, 
2	(CASE EXTRACT(YEAR FROM hiredate)
3		WHEN 1982 THEN '3 years service'
4		WHEN 1981 THEN '4 years service'
5		WHEN 1980 THEN '5 years service'
6		END) AS "Award for 2000"
7		FROM emp
8		WHERE EXTRACT(YEAR FROM hiredate) IN  (1982,1981,1980)
9		ORDER BY hiredate;

위의 간단한 CASE 표현식에 대한 출력 결과는 다음과 같다. 
ENAME	Award for 2000
---------------	---------------------------
SMITH	5 years service
ALLEN	4 years service
WARD	4 years service
JONES	4 years service
BLAKE	4 years service
CLARK	4 years service
TURNER	4 years service
MARTIN	4 years service
KING	4 years service
JAMES	4 years service
FORD	4 years service
MILLER 	3 years service
12 rows selected.

 

검색 CASE 표현식

 

검색 CASE 표현식은 IF...THEN ELSE 구조와 유사하며, 표현식 내에서 조건에 따른 검색과 값들의

치환을 하는 데 사용될 수 있다. 각 WHEN 조건은 논리적 연산자(AND, OR 등)와 결합되어 사용될 수 있으며,

조건 표현식에서 비교 연산자를 사용할 수 있다. 따라서, 간단한 CASE 표현식보다는 유연하다고 할 수 있다.

예를 들어 EMP 테이블에서 Sal 열의 범위에 따른 영역을 표현하는 SQL문과 결과는 다음과 같다.

 

SQL> SELECT empno, ename,(CASE
2	WHEN sal >= 5000 THEN 'High Sal'
3	WHEN sal >= 3000 AND sal < 5000 THEN 'Middle Sal'
4	WHEN sal >= 1000 AND sal < 3000 THEN 'Average Sal'
5	WHEN sal < 1000 THEN 'Low Sal'
6	END) AS Sal_Category
7	FROM emp;

EMPNO	ENAME	SAL_CATEGORY
-------------	-------------	-------------------------
7369	SMITH	Low Sal
7499	ALLEN	Average Sal
7521	WARD	 Average Sal
7566	JONES	Average Sal
7654	MARTIN	Average Sal
7698	BLAKE	Average Sal
7782	CLARK	Average Sal
7788	SCOTT	Middle Sal
7839	KING	High Sal
7844	TURNER	Average Sal
7876	ADAMS	Average Sal
7900	JAMES	Low Sal
7902	FORD	Middle Sal
7934	MILLER	Average Sal

 

NULLIF 함수

 

NULLIF 함수의 경우 첫 번째 입력 인자와 두 번째 입력 인자가 같은 경우에는 NULL을 반환하고,

그렇지 않을 경우에는 첫 번째 입력 인자의 값을 반환한다. 예를 들어, EMP 테이블의 사원 중에 Sal 열의

값이 5000인 사람에 대해 NULLIF 함수를 적용하는 SQL 문은 다음과 같다.

 

SQL> SELECT ename, sal
2	FROM emp
3	WHERE NULLIF(sal, 5000) IS NULL;

 

만약 NULLIF 함수를 CASE 문으로 나타낸다면 다음과 같다.

 

CASE 
WHEN expression1 = expression2 THEN NULL
ELSE expression1
END CASE

 

COALESCE 함수

 

COALESCE 함수는 Oracle의 NVL 함수를 일반화한 것이다. 즉, 첫 번째 입력 인자가 Null이 아닐 경우에는

첫 번째 입력 인자를 반환하고, 아닐 경우에는 두 번째 표현식에 대해서 평가를 계속하게 된다. 예를 들어,

EMP 테이블에서 COMM 열의 값이 Null인지 검사하는 SQL 문은 다음과 같다.

 

SQL> SELECT ename, COALESCE(comm,'NULL')
2	FROM emp;

 

NULLIF 함수와 유사하게 CASE 문으로 나타내면 다음과 같다.

 

CASE
	WHEN expression1 IS NOT NULL THEN expression1
	ELSE expression2
END CASE;

 

NVL 함수에 비해 COALESCE 함수의 장점은 여러 대체 값을 취할 수 있다는 것이다. 예를 들어, 첫 번째

입력 인자가 Null일 경우에는 나머지 표현식에 대해서 COALESCE를 계속 적용하는 것이 가능하다.

 

객체관계형 데이타베이스(ORDB)의 완성을 위한 상속

 

관계형 DBMS를 사용하는 애플리케이션의 범위가 기존의 정형화된 데이타에서 점점 더 다양하고 복잡한

데이타를 필요로 하는 영역으로 확장됨에 따라, DBMS는 텍스트, 이미지, 오디오, 비디오 등과 같은

멀티미디어 데이타와 CAD, CAM, CASE 등의 복합 객체, 반 구조적 데이타인 XML, 메시지, 다양한

문서 포맷 등을 처리해야 한다.

 

이와 같이 복잡한 데이타를 DB에 저장, 관리할 수 있는 기능을 효과적으로 지원하기 위한 해답으로서

많은 DBMS 업체들은 객체지향 개념을 도입하기 시작하였다. 오라클도 Oracle8.0부터 객체, 객체 뷰,

메소드, 복합 객체, 컬렉션 등 객체지향 관련 개념을 지원하고 있다. 객체지향 개념을 지원함으로써 오라클

데이타베이스에서 객체 개념을 모델링할 수 있고, 멀티미디어/XML 등의 데이타를 지원할 수 있고,

확장 프레임워크를 통해서 새로운 타입의 데이타와 이에 대한 연산을 추가할 수 있게 되었다.

 

Oracle9i에서는 한 걸음 더 나아가 객체지향(Object Orientation) 개념과 관련해서 상속(Inheritance),

타입 진화(Type Evolution), 멀티레벨 컬렉션(Multilevel Collection) 등의 기능을 제공한다.

특히 상속(Inheritance) 개념을 지원함으로써, Oracle9i는 진정한 의미의 객체관계형 DBMS로

자리매김하게 되었다.

 

상속 개념을 지원함으로써, 오라클 데이타베이스 내에서 자연스러운 객체 모델링이 가능해졌으며,

객체 재사용성이 증가하였다. Java, C++ 등의 애플리케이션의 객체 모델과 DB 객체 모델의 동일성 등의

장점을 제공하게 된다. 그러면, Oracle9i의 상속 개념들을 설명하고 이 기능들을 예제를 중심으로 테스트한

내용을 설명한다.

 

타입, 하위타입, 타입 계층구조에 대한 상속

 

타입은 자신의 멤버(member)와 메소드(member function와 member procedure)를 갖는다. 하나의

타입 T1에서 상속을 통해서 새로운 타입 T2를 정의할 수 있다. 이때 T1을 T2의 상위타입(supertype),

T2를 T1의 하위타입(subtype)이라 한다. 하위타입은 상위타입의 모든 멤버와 메소드를 상속 받는다.

또한, 하위타입에서 추가로 자신의 멤버와 메소드를 정의할 수 있다.

 

Oracle9i는 하나의 상위타입에서 상속받은 단일상속(single inheritance)만을 가질 수 있다. 즉, 둘

이상의 상위타입에서 상속하는 다중상속(multiple inheritance)은 지원하지 않는다. 그러나, 하나의 상위타입에서

하나 이상의 하위타입을 정의할 수 있다. 이들 타입간의 상하위 관계를 타입 계층구조(type hierarchy)라 한다.

단일상속 모델에서 타입 계층구조는 트리 구조가 된다. 타입 계층구조의 최상위 타입을 루트 타입(root type)이라 한다.

<그림 1>은 Person_T를 루트 타입으로 하는 타입 계층구조의 예이다.

 

FINAL 대 NOT FINAL 타입

 

특정 타입을 NOT FINAL로 선언하면 이 타입에서 상속을 통해 하위타입을 생성할 수 있다. 그러나,

특정 타입을 FINAL로 선언하면 이 타입으로부터는 상속이 불가능하다. 예를 들어, <그림 1>의 예에서

타입 Person_T는 NOT FINAL로 선언되었기 때문에 하위타입 생성이 가능했다. 그러나, Student_T 타입을

정의할 때, FINAL로 선언했다면 Student_T에서는 하위타입을 생성할 수 없다. 타입 선언은 디폴트로

FINAL로 지정된다.

 

NOT INSTANTIABLE 타입과 메소드

 

일반적으로 타입을 정의하고 이 타입에서 객체를 생성할 수 있다. 그런데, 타입 선언시에 NOT INSTANTIABLE로

지정을 하면 해당 타입의 객체를 생성할 수 없다(C++ 언어의 추상 클래스(abstract class)와 개념이

동일하다). NOT INSTANTIABLE 타입의 목적은 하위타입들에 공통으로 필요한 멤버와 메소드를 정의해 두고,

하위타입에서는 이들 멤버와 멤버함수를 상속받아서 사용하게 하는 데 있다. 타입 선언은 디폴트로

INSTANTIABLE이다.

 

이와 유사하게 특정 메소드의 경우에 각각의 하위타입에서 구현이 제각각 다른 경우에는 해당 멤버 함수를

NOT INSTANTIABLE하게 선언해 두고, 각각의 하위타입에서 자신에 맞는 메소드를 구현해야 한다.

 

메소드 오버라이딩과 오버로딩 사용자는 상위타입에서 상속받은 메소드를 자신의 타입에 맞도록 재정의할

수 있는데, 이를 메소드 오버라이딩(method overriding)이라 한다. 예를 들어, <그림 1>의 예에서

Person_T에 print()라는 메소드가 정의되어 있는데, Student_T에서는 이 print() 메소드에 Student_T에서

정의된 멤버의 정보를 추가적으로 출력할 필요가 있다. 이때는 print() 메소드를 자신의 타입에 맞도록

재정의해야 한다.

 

반면, 상위타입에서 상속받은 메소드와 이름은 같지만, 인자의 타입이 다른 메소드를 정의할 수 있다.

이를 메소드 오버로딩(method overloading)이라 한다. 즉, 하나의 메소드 이름에 대해 인자의 타입에 따라

서로 다른 메소드가 불려지게 된다. 예를 들어, + 연산자의 경우 피연산자가 정수인 경우와 실수인 경우

계산방식이 다른데, 이는 + 연산자의 의미가 오버로딩된 것이다.

 

Dynamic Method Dispatch

                Person_T
                 /        \
        Student_T     Emp_T
                              |
                            Prof_T

<그림 1> 타입 상속의 예

 

메소드 디스패치

 

예를 들어, 다음과 같은 Person_T 타입 변수가 있다고 가정하자.

 

person Person_T;

 

상속 개념에 따르면, 이 변수에는 다음과 같이, Person_T의 객체뿐만 아니라, 하위타입인

Student_T의 객체도 할당(assign)될 수 있다.

 

person := Person_T(...); /* Person_T 객체 */
person.print();
person := Student_T(...); /* Student_T 객체 */
person.print();

 

하위타입 생성

 

<리스트 1>은 <그림 1>의 Person_T 타입과 Student_T 타입을 상속을 통해서 생성한 예이다.

<리스트 1>은 앞에서 설명한 상속과 관련한 개념들을 표현하고 있다. <리스트 1>의 CREATE TYPE Student_T

부분의 내용을 살펴보면 Student_T는 Person_T 의 하위타입이며 Person_T는 NOT FINAL로 선언되었고

Student_T는 FINAL로 선언되었다. 또한 Student_T의 메소드 foo()는 Person_T에서 상속받은 foo()에

대한 오버라이딩이며, Student_T의 메소드 foo(x NUMBER, y NUMBER)는 상속받은 fod(x NUMBER)에

대한 오버로딩이다.

 

두 타입에 정의된 메소드의 역할은 다음과 같다. age()는 출생년도에서부터 나이를 계산해서 리턴하며

Person_T::foo(x NUMBER)는 (x+1)를 리턴하고 Student_T::foo(x NUMBER)는 (x-1)를 리턴,

그리고 Student_T::foo(x NUMBER, y NUMBER)는 (x+y)를 리턴한다.

 

CREATE TYPE Person_T AS OBJECT
(	name VARCHAR2(10),
	address VARCHAR2(20),
	birth_year NUMBER(4),
	FINAL MEMBER FUNCTION age RETURN NUMBER,
	MEMBER FUNCTION foo(x NUMBER) RETURN NUMBER
) NOT FINAL;

CREATE OR REPLACE TYPE BODY Person_T IS
	FINAL MEMBER FUNCTION age RETURN NUMBER IS
	BEGIN
		RETURN 2001 - birth_year;
	END;
	MEMBER FUNCTION foo(x NUMBER) RETURN NUMBER IS
	BEGIN
		RETURN (x + 1);
	END;  
END;

CREATE OR REPLACE TYPE BODY Person_T IS
	FINAL MEMBER FUNCTION age RETURN NUMBER IS
	BEGIN
		RETURN 2001 - birth_year;
	END;
	MEMBER FUNCTION foo(x NUMBER) RETURN NUMBER IS
	BEGIN
		RETURN (x + 1);
	END;  
END;

CREATE TYPE Student_T UNDER Person_T
(	deptid NUMBER,
major  VARCHAR2(20),
OVERRIDING FINAL MEMBER FUNCTION foo(x NUMBER) RETURN NUMBER,
	MEMBER FUNCTION foo(x NUMBER, y NUMBER) RETURN NUMBER  
); 

CREATE OR REPLACE TYPE BODY Student_T IS
	OVERRIDING FINAL MEMBER FUNCTION foo(x NUMBER) RETURN NUMBER IS
	BEGIN
		RETURN (x - 1);
	END;
	MEMBER FUNCTION foo(x NUMBER, y NUMBER) RETURN NUMBER IS
	BEGIN
		RETURN (x + y)
	END;

END;


 하위타입 생성

 

멤버와 메소드 상속

 

위와 같이 Person_T와 Student_T를 생성하고, 'desc Student_T' 명령을 이용해서 Student_T에

대한 정보를 조회하면 <리스트 2>와 같다. <리스트 2>에서 다음과 같은 사실을 알 수 있다. student_t는

person_t의 하위타입이며, person_t의 멤버 NAME, ADDRESS, BIRTH_YEAR와 메소드 AGE를

상속하고 student_t의 FOO(x)는 오버라이딩, FOO(x,y)는 오버로딩이다.

 

메소드 오버로딩

 

이제 메소드 오버로딩에 대해 알아보자. Student_T에는 foo라는 같은 이름을 가진 두 개의 메소드가

정의되어 있다. 이제 다음과 같은 PL/SQL 문을 수행하면 각각 0, 3의 결과를 수행해야 한다. 즉,

인자의 개수와 타입에 따라 서로 다른 foo 메소드가 호출되어야 한다.

 

DECLARE
student Student_T;
BEGIN
	student := student_t('Carey', 'Proper Street 3', 1982, 500, 
	  'Chemistry');
	dbms_output.put_line('Foo(x NUMBER)...................:' || 
	  student.foo(1) || '.');
	dbms_output.put_line('Foo(x NUMBER, y NUMBER).... :' || 
	  student.foo(1,2) || '.');
END;

 

이때 결과는 다음과 같다.

 

Foo(x NUMBER) .......           :0.
Foo(x NUMBER, y NUMBER) .... :3.

 

지금까지 Oracle9i에서부터 새로이 제공되는 상속의 개념과 사용법에 대해 알아보았다.

 

Student_t extends SCOTT.PERSON_T
Name	                 Null?        	Type
----------------------	--------------	------------------
NAME			VARCHAR2(10)
ADDRESS			ARCHAR2(20)
BIRTH_YEAR		NUMBER(4)
DEPTID			NUMBER
MAJOR			VARCHAR2(20)

METHOD
------
FINAL MEMBER FUNCTION AGE RETURNS NUMBER
METHOD
------
MEMBER FUNCTION FOO RETURNS NUMBER
Argument Name		Type	     In/Out Default?
----------------------	------------ ------ --------------
X			NUMBER	      IN

METHOD
------
MEMBER FUNCTION FOO RETURNS NUMBER
Argument Name		Type	     In/Out Default?
----------------------	------------ ------ --------------
X			NUMBER	       IN
Y			NUMBER	       IN

 멤버와 메소드 조회 결과

 

ORDB 지원을 위한 타입 진화

 

타입 진화(Type Evolution)는 객체 타입에 변경하는 작업을 일컫는다. Oracle9i 이전에는 타입에

새로운 메소드를 추가하는 연산을 허용하고 있다. 오라클9i에서는 타입 상속 개념을 지원하면서 이 타입

계층구조상의 타입들에 대한 다양한 변경작업을 지원한다. 즉, '타입 진화' 기능을 제공한다.

타입 상속은 순수 객체지향 DBMS에서도 이와 유사한 기능을 제공하는데, 주로 '스키마 진화(Schema Evolution)'

라는 용어를 사용하고 있다. 이 타입 진화 기능은 특히 ERP, 공간 데이타(spatial data), 멀티미디어

응용 분야에서 많이 요구되고 있다.

 

Oracle9i부터 지원하는 타입 변경 오퍼레이션들은 속성의 추가/삭제, 메소드 추가/삭제, 내장(built-in)

타입 속성(길이, 자리수 등) 변경, 타입 FINAL/INSTANTIABLE 속성 변경, 타입 변경과 의존

스키마 객체(dependent schema objects) 등을 들 수 있다.

 

특정 타입을 직/간접으로 참조하고 있고, 해당 타입 변경에 영향을 받는 모든 스키마 객체를

의존 객체(dependent object)라 한다. 여기에서는 <그림 2>의 샘플 스키마를 대상으로 타입 변경의 내용을

설명하겠다. 이 샘플 스키마의 타입 계층구조, 객체 테이블, 뷰 계층구조를 보여 준다.

 

<리스트 3>은 <그림 2>에 해당하는 스키마 생성 스크립트이다. 위의 샘플 스키마의 Person_T에 예를

들어 다음과 같이 주민등록번호를 추가하는 타입 변경을 가정해 보자.

 

ALTER TYPE Person_T ADD ATTRIBUTE(ssn VARCHAR2(13)) 
CASCADE;

 

위에서 옵션 CASCADE는 현재의 타입 변경의 효과를 의존 객체에 바로 적용하라는 의미이다.

위 타입 변경의 결과로 Person_T, Student_T 타입 객체, 그리고 Person, Student 테이블에 ssn 항목이

추가되었음을 <리스트 4>에서 확인할 수 있다. 그리고, 다음에서처럼 Person 테이블을 검색해

보면 행 객체 단위에서도 ssn 속성이 추가되었음을 알 수 있다(Student 테이블도 마찬가지이다).

 

SQL> select * from person;
NAME	     ADDRESS	       BIRTH_YEAR   SSN
----------- -----------------  ------------ ----------
Andy	     Alington Street 1 1980        (NULL)

 

/* Type Hierarchy */
/* List 3 시작 */
SQL> CREATE TYPE Person_T AS OBJECT
	2	( name VARCHAR2(10),
	3	address VARCHAR2(20),
	4	birth_year NUMBER(4),
	5	FINAL MEMBER FUNCTION age RETURN NUMBER,
	6	MEMBER FUNCTION foo(x NUMBER) RETURN NUMBER
	7	) NOT FINAL;

SQL> CREATE OR REPLACE TYPE BODY Person_T IS  ...END;

SQL> CREATE TYPE Student_T UNDER Person_T
	2	( deptid NUMBER,
	3	major  VARCHAR2(20),
	4	OVERRIDING MEMBER FUNCTION foo(x NUMBER) RETURN NUMBER);

SQL> CREATE OR REPLACE TYPE BODY Student_T IS  ... END;

/* Object Tables */
SQL> CREATE TABLE Person of Person_T (name PRIMARY KEY);
SQL> CREATE TABLE Student of Student_T;

SQL> INSERT INTO Person VALUES('Andy', 'Alington Street 1', 1980);
SQL> INSERT INTO Student VALUES('Bob', 'Berkeley Street 2', 1978, 1000, 'Comp. Science');

/* Object View Hierarchy */
SQL> CREATE VIEW Person_V of Person_T WITH OBJECT ID (name)
	2	AS
	3	SELECT name, address, birth_year
	4	FROM Person;

SQL> CREATE VIEW Student_V of Student_T UNDER Person_V
	2	AS
	3	SELECT *
	4	FROM Student;

 타입 변경을 위한 스키마 생성

 

/* List 4 시작 */
SQL> desc Person_T
person_t is NOT FINAL
Name 	           Null?	Type
----------------- ------------ -----------
NAME			       VARCHAR2(10)
ADDRESS		               VARCHAR2(20)
BIRTH_YEAR		       NUMBER(4)
SSN		               VARCHAR2(13)
....

SQL> desc Student_T
Student_T extends SCOTT.PERSON_T
Name 	           Null?	Type
----------------- ------------ -----------
NAME		               VARCHAR2(10)
ADDRESS		               VARCHAR2(20)
BIRTH_YEAR		       NUMBER(4)
SSN		               VARCHAR2(13)
DEPTID		               NUMBER
MAJOR		VARCHAR2(20)
...

SQL> desc Person
Name 	           Null?	Type
----------------- ------------ -----------
 NAME 	          NOT NULL	VARCHAR2(10)
 ADDRESS	        	VARCHAR2(20)
 BIRTH_YEAR		        NUMBER(4)
SSN		                VARCHAR2(13)
 ...

SQL> desc Student
Name 	           Null?	Type
----------------- ------------ -----------
 NAME		               VARCHAR2(10)
 ADDRESS	               VARCHAR2(20)
 BIRTH_YEAR 		       NUMBER(4)
 SSN		               VARCHAR2(13)
 DEPTID		               NUMBER
 MAJOR		               VARCHAR2(20)
 ...

 타입 변경 결과 확인

 

 

데이타베이스 XML 기능

 

인터넷상에서 일어나는 모든 정보 교환의 표준으로서 XML의 역할이 점점 더 커지고 있다. 'XML은

옵션이 아니라 대세다.'라는 말을 쉽게 들을 수 있는데, 데이타베이스에서 XML을 읽고 쓸 수 있고,

또 기존 애플리케이션에 XML 데이타를 통합할 수 있는 기능은 필수적이다.

 

이러한 XML을 다른 데이타타입처럼 쉽게 다룰 수 있게 도와주는 것이 XDK(XML Developer's Kit) 이며,

Oracle9i에서는 몇 개의 컴포넌트가 더 추가되었고 기존의 컴포넌트도 그 기능이 더 향상되었다. 가장

큰 변화는 XML Schema 1.0을 지원하는 것인데, 새로운 컴포넌트는 XML Schema Processors와

XDK Java Beans(DBAccess Class, DBViewer Bean)이다.

 

또한 Oracle9i에서 가장 눈에 띄는 기능으로, 새롭게 추가된 데이타타입으로 XMLTYPE을 들 수 있다.

XDK는 현재 http://otn.oracle.co.kr에서 무료로 다운로드 받을 수 있으며, 여러 샘플을 해당

사이트에서 접할 수 있을 것이다. 여기에서는 Oracle9i에 XML을 특정 데이타타입으로 저장할 수

있는 기능인 XMLTYPE에 대해 설명하기로 하자.

 

XMLType

 

Oracle9i에서 XMLType이라는 새로운 데이타타입을 제공한다. XMLType은 XML 문서를 CLOB처럼

저장하며, Contains operator와 XPath-like syntax를 써서 Oracle9i Text (interMedia Text) 인덱스를

사용할 수 있다. 현재 버전에서는 서버단에서만 PL/SQL, SQL을 사용해서 XMLType을 이용할 수 있으며,

현재는 CLOB으로만 저장되지만, 추후에는 BLOBs, NCLOBs 등으로 확장될 것이다.

그러면, 사용 예를 살펴보기로 하자.

 

<리스트5>는 XMLType 열을 가진 테이블에 XML 문서를 삽입하고, extract(), existsNode(),

getClobVal(), getStringVal()과 같은 함수를 사용하여 XML 문서를 읽는 예제이다.

 

/*List 5 시작 */
SQL> CREATE TABLE po_tab (
	2	pono	number primary key, 
	3	orderdate	date,  
	4	poxml	sys.XMLType);

SQL>	insert into po_tab values 
	(100, TO_DATE('February 07, 2001', 'Month dd, YYYY'),
sys.xmltype.createXML
	(' PO_1
	   '));

SQL>	insert into po_tab values 
	(200, TO_DATE('February 07, 2001', 'Month dd, YYYY'), 
sys.xmltype.createXML
	('PO_2'));

SQL>	insert into po_tab values 
	(300, TO_DATE('February 07, 2001', 'Month dd, YYYY'), 
sys.xmltype.createXML
	('한글'));

SQL>	select e.poxml.getclobval() from po_tab e;

E.POXML.GETCLOBVAL()
------------------------------------------------------------------
PO_1
PO_2
한글

SQL> select e.poxml.extract('/PO/PONAME').getClobVal() 
	2 from po_tab e 
	3 where e.poxml.existsNode('/PO/@pono') = 1 and     
	4 e.poxml.extract('/PO/@pono').getStringVal() = '100' and       
	5 e.poxml.extract('/PO/PONAME').getStringVal() like '%PO%';

E.POXML.EXTRACT('/PO/PONAME').GETCLOBVAL()
------------------------------------------------------------------
PO_1

 테이블에 XML 문서 저장 및 읽기

 

Datetime 데이타타입과 Interval 데이타타입

 

Oracle9i 안의 모든 Datetime 데이타타입과 Interval 데이타타입은 ANSI SQL 99 표준과 순응한다.

이를 위해서 Datetime 데이타타입으로는 timestamp, timestamp with timezone, timestamp with

local time zone 타입이, Interval 데이타타입으로는 interval year to month, interval day to

second 타입이 추가되었다. 이 글에서는 새롭게 추가된 데이타타입의 사용예와 함께 Oracle9i에서

추가된 날짜 관련 함수들의 사용 예를 살펴본다.

 

ANSI SQL:99는 Datetime과 Interval에 대한 타입으로 총 18개의 타입을 제시하고 있다. Datetime

데이타타입으로는 date, time, time with time zone, timestamp, timestamp with time zone의

5개의 타입으로 이 중 time, time with time zone을 제외한 타입을 지원하며, 오라클만의 Datetime 타입으로

timestamp with local time zone이 있다. Interval 타입에는 13개가 있으나 그 중에서 오라클은 interval

year to month, interval day to second 타입만을 지원한다.

 

Datetime 데이타타입

 

timestamp, timestamp with time zone, timestamp with local time zone 이 세 가지 Datetime 타입 모두 년,

월, 날짜, 시간, 분, 소수점 아래 정보를 가지고 있는 초와 같은 시간 정보를 가지고 있다. 이러한

정보들은 의미가 있는 값을 가져야 하며 이 각각의 정보들이 가질 수 있는 값은 <표 1>과 같다. 이 각각의

Datetime 타입은 모두 위의 필드 값을 가지고 있으나 그 차이점은 시간대(time zone) 정보를 가지고

있느냐, 가지고 있다면 어떠한 형태로 가지고 있느냐의 차이이다.

 

 

Datetime Field                              올바른 값 
Year                                           -4712...999 (0의 값은 가질 수 없다.) 
Month                                         01 to 12 
Day                                            01 to 31 
Hour                                           00 to 23 
Minute                                        00 to 59 
Sencone                                     00 to 59.9(N), 소수점 아래 9자리까지 가능 
Timezone_Hour                           -12 to 13
(시간대를 GMT와의 차이 시간으로 나타낼 때 쓰이는 값) 
Timezone Minute                          00 to 59 

<표 1> Datetime 필드와 값 

 

Timestamp

 

Timestamp 타입은 Datetime 타입의 확장형이다. 이는 년, 월, 날짜에 덧붙여 시간, 분,

초의 정보를 가지고 있다. 초 밑에 소수점 아래 몇 자리까지 나타낼 것인지는 선언시에 정의하여

주면 된다. 아래의 예제에서는 소수점 아래 5자리까지 나타낸다. 이 값을 명시하지 않으면

기본으로 6자리까지 나타낸다.

 

SQL> create table timestamp_test( timestamp_a timestamp(5)) ;

 

Timestamp 타입과 Datetype 타입의 차이는 먼저 단순한 디스플레이에서 차이가 난다. Datetime

타입은 to_char 함수를 사용하여 날짜 포맷을 변환시켜서 사용하지 않는 경우에는 단순히 년, 월,

날짜에 대한 정보만 나타낼 수 있다. 그리고 가장 큰 차이점은 Datetime 타입은 to_char 함수를

이용하여도 초 정보에 있어서 소수점 아래 0부터 -60까지의 값만 나타낼 수 있는 데 반하여 Timestamp

타입은 소수점 아래 정보까지 나타낼 수 있다.

 

그러면, 기존에 제공하던 Datetime 데이타타입과 Oracle9i에 새롭게 추가된 Timestamp 데이타타입과의

차이점을 비교해 보도록 하자. 다음은 기존에 제공하던 Datetime 데이타타입을 사용한 예제이다.

 

SQL> select sysdate from dual ;
SYSDATE
-----------------
01/04/10

SQL> select to_char(sysdate, 'YY-MM-DD HH:MM:SS AM') from dual
TO_CHAR(SYSDATE,'YY-MM
---------------------------------------
01-04-10 04:04:45 오후

 

그리고 다음은 Oracle9i에서 새롭게 추가된 Timestamp 데이타타입의 예제이다.

 

SQL> create table date_test (
                2  today_date timestamp ) ;
Table created

SQL> select today_date from date_test ;
TODAY_DATE
-----------------------------------------------------------
01/04/09 15:53:40.081711 -- 2001년 4월 9일 15시 53분 40.081711

 

Datetime 데이타타입과 Interval 데이타타입

 

Local Time Zone의 Timestamp

 

이 타입은 Timestamp의 하나의 변형으로 내부적으로 Timezone 정보를 가지고 있다. 이 타입이

timestamp with time zone과 차이가 있다면 time zone 정보를 직접적으로 열의 일부로 저장하는

것이 아니라 데이타베이스 세션 정보를 이용한다. 그래서 데이타베이스 세션 정보의 time zone 정보를

수정하면 전체 데이타 또한 같이 수정된다. 이를 <리스트6>를 통하여 직접 확인해 보도록 하자.

 

<리스트 6>에서 보면 '+09:00' 시간대에서는 '01/04/09 16:54:56.000000' 값을 가진 데이타가 'US/Pacific'(-08:00) 시간대에서는

'01/04/09 00:54:56.000000'으로 변한다.

 

SQL> desc date_test2
 Name	Null?	Type
 ---------------------------- --------- ------------------------------------------------
 TODAY	TIMESTAMP(6) WITH LOCAL TIME  ZONE

SQL> select * from date_test2 ;
TODAY
--------------------------------------------------------
01/04/09 16:54:56.000000
99/04/16 00:00:00.000000

SQL> select sessiontimezone from dual ;
SESSIONTIMEZONE
-------------------------------------------------------
+09:00

SQL> alter session set time_zone = 'US/Pacific' ;
Session altered.

SQL> select sessiontimezone from dual ;
SESSIONTIMEZONE
-------------------------------------------------------
US/Pacific

SQL> select * from date_test2 ;
TODAY
---------------------------------------------------------
01/04/09 00:54:56.000000
99/04/15 08:00:00.000000

 Local Timezone의 예

 

Oracle9i Database 고가용성(HA) 아키텍처

 

고가용성(High Avalability)은 일정 계획에 따른 백업이나 재난 상황에서도 데이타베이스에 저장된 데이타를

애플리케이션에서 액세스하고 이용할 수 있는 것을 의미한다. Oracle9i Database는 시스템의 고가용성

과제를 해결하는 데 도움이 되는 일련의 컴포넌트들을 갖추고 있다. 대표적으로, 서버의 고가용성과 확장성을

위한 Real Application Clusters, 장애 발생 시스템의 신속한 온라인 복구를 지원하는 Fast Restart, 데이타의

손상, 손실을 예방하는 Recovery Manager, 사람에 의한 실수를 방지하는 Flashback Query와 Log Miner,

그리고, 데이타베이스를 오프라인으로 만들지 않고 일상 유지보수를 수행할 수 있는 Online Redefinition 등이 있다.

 

Oracle9i 데이타베이스의 고가용성을 보장하는 또 다른 특징은 Data Guard이다. Data Guard는 사람의

실수나 각종 재난, 스토리지 장애 및 예고된 시스템 중단으로부터 데이타를 보호한다. Data Guard는

단순히 '보호' 이상의 역할을 수행한다. 스탠바이 시스템의 모니터링과 제어 관련 작업들을 자동화해

주므로, 스탠바이 시스템을 유지보수나 리포트용으로 사용해 실제 작업중인(프로덕션) 시스템의 프로세싱

로드를 덜어 줄 수 있다.

 

아래 그림에서 QuickStar 은행은 Data Guard를 사용해 자사 스탠바이 사이트와 프로덕션 데이타베이스의

동기화 프로세스를 자동화했다. 그 결과, 사용자가 프로덕션 시스템에서 은행 레코드를 갱신하면, 로그

파일이 바로 프로덕션 시스템에서 스탠바이 시스템으로 기록된다.

 

QuickStar 은행의 DBA인 Chandra가 Data Guard의 '지연 적용(delayed apply)' 기능을 활성화시키자,

스탠바이 시스템에 도착한 로그 파일이 바로 적용(기록)되지 않고, Chandra가 파일의 에러를 수정할

기회를 준다. 또, QuickStar 은행의 스탠바이 시스템은 리포팅 데이타베이스로서 셋업되어 있어, 프로덕션

시스템의 프로세싱 로드를 덜어 준다.

 

QuickStar 은행의 개발자들은 Data Guard 기능 외에도, Oracle9i Flshback Query를 사용해 다양한

애플리케이션에서 셀프서비스 에러 수정 기능을 만들었다. 이렇게 함으로써, Gilbert 같은 사용자는

DBA인 Chandra의 도움을 받지 않고도 실수로 레코드를 지우거나 파괴한 자신의 실수를 직접 수정할 수

있다. 또, Chandra는 데이타베이스의 온라인 상태를 유지하면서 일상 유지보수 업무를 수행할 수 있다.

데이타베이스의 스키마를 인식하고, 테이블과 인덱스를 변경하고, 인덱스를 재작성하거나 세분하며, 저장된

프로시저(stored procedures)를 갱신할 수 있는 것이다.

[Top]
No.
제목
작성자
작성일
조회
8195오라클 9i 의 10 가지 새로운 기능 [1]
정재익
2001-10-31
8491
8193RMAN New Features in Oracle 9i
정재익
2001-10-31
5216
8185DataWarehousing (ETL) Enhancements in Oracle 9i
정재익
2001-10-31
4965
7513개발자들을 위한 Oracle9i의 신기능
정재익
2001-09-24
16193
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.020초, 이곳 서비스는
	PostgreSQL v16.2로 자료를 관리합니다