Oracle 에서 Informix 로 Porting 하는 가이드
A Discussion of the Application Porting Issues
Informix Dynamic Server Version 7.3x
CHAP 1. 소개
CHAP 2. DDL
2.1 식별자(Identifiers)
식별자는 데이터베이스, 테이블, 컬럼, 인덱스, 뷰, 프로시저 등의 데이터베이스 오브젝트를 나타내는 이름이다.
2.2 데이터베이스 (Databases)
※ ANSI 데이터베이스의 특징
트랜잭션이 암시적(implicitly)으로 정의되므로 begin work 문장이 필요없이 모든 문장이 트랜잭션안에 들어간다.
데이터베이스의 모든 오브젝트는 소유자(owner)의 이름을 필요로 한다.
Grant to public 개념이 없으므로 각각의 사용자에게 권한을 부여해야 한다.
2.3 테이블 (Tables)
※ constraint 정의 구문 예제
※ Informix의 alter table 구문은 좀 더 풍부한 기능을 제공한다
- 컬럼 추가 및 삭제, 컬럼명 변경, next size변경, lock mode변경 등
2.4 자료형 (Data types)
※ NULL , 공백 문자열
오라클의 빈(empty) varchar 컬럼은 null로 간주한다.
공백이 들어간 문자열의 비교에서 오라클을 공백을 문자열 간주하고 인포믹스는 공백을 무시한다, 즉 오라클은 "abc" != "abc " 이고, 인포믹스는 "abc" = "abc " 이다.
2.5시퀀스 (Sequences)
2.6 인덱스 (Indexes)
2.7 뷰 (Views)
2.8 스토어드 프로시저 (Stored Procedures)
2.9 오라클 확장형 (oracle extensions)
CHAP 3. DML
3.1 SQL
3.1.1 selects
데이터를 읽어오는데 가장 적합한 방법을 옵티마이저가 어떻게 결정하느냐에 의해 질의가 실행 된다. 오라클과 인포믹스 7.3버전 이후 서버는 select문에서 옵티마이저 힌트를 사용할 수 있다.
3.1.2 Optimizer Directives
인포믹스 7.3이후 부터 오라클과 흡사한 옵티마이저 지시자(directives)를 제공한다.
질의가 수행될 때의 첫번째단계는 질의에 대한 최적화 경로를 찾아 컴파일하고 두번째 단계로 결과값을 출력한다.
인포믹스의 옵티마이저 지시자는 오라클의 옵티마이저 힌트와 구문과 동작에서 호환성이 있다.
지시자는 '+'기호가 따라오는 주석(comment)안에서 사용된다.
예)
select {+ ORDERED AVOID FULL(e)} * from employee e, department d
where e.dept_no = d.dept_no;
오라클의 직접적인 힌트외에 인포믹스는 유일하게 negative directives 의 개념을 제공한다. 즉, 옵티마이저가 피하는 (avoid) 최적화 방법을 지시할 수 있다. 또한 set explain 의 출력결과에서 옵티마이저 지시자에 대한 모든 정보를 알 수 있어 지시어의 의미 또는 구문 에러를 표시할 수 있다.
옵티마이저 지시자는 다음과 같은 최적화 프로세스를 제어할 수 있다
· Access methods: 인덱스 또는 전체 스캔.
· Join Methods: hash join 또는 nested loop joins.
· Join Order: 지정한 테이블 순서에 의해 join
· Goal: first rows 또는 all rows (최초 응답시간 대 전체 산출 결과).
3.1.3 Inserts
INSERT INTO…SELECT 구문을 사용할 때 인포믹스는 select절에 union 을 사용할 수 없고, INSERT INTO…VALUES 에서 수식이나 select절을 사용할 수 없다. 이러한 경우 select에 대한 결과를 INTO TEMP 절을 사용하여 임시테이블을 생성하고, INSERT INTO…SELECT 절 구문을 임시테이블로 부터 읽어와서 입력하도록 재작성해야한다.
3.1.4 Deletes
오라클의 DELETE table_name 구문은 DELETE FROM table_name 구문으로 고쳐야한다
3.1.5 Temporary Tables
인포믹스와 오라클의 temporary table은 개념에 있어서 많이 다르다.
오라클의 temporary table은 하나의 필드를 포함하는 배열과 같이 구현되어 있다.
인포믹스의 temporary table은 일반 테이블과 동일하게 구현되어 생성, 변경, 삭제 등의 작업을 할 수 있지만, 세션안에서만 유효하다.
3.1.6 Joins
오라클의 outer join 구문 + (조인 테이블의 컬럼에 부합하지 않는 값을 가진 컬럼의 뒤에 붙는다) 는 인포믹스의 OUTER 구문과 동일하다. OUTER 키워드는 테이블명 앞에 붙는다. 오라클과는 달리 괄호로 그룹화되어 복합(multiple) outer join을 허용한다.
오라클의 INTERSECT와 MINUS 오퍼레이터는 UNION과 비슷하다. INTERSECT는 인포믹스에서 WHERE EXISTS 나 WHERE … IN으로 교체할 수 있고, MINUS는 WHERE NOT EXISTS 또는 WHERE … NOT IN으로 교체할 수 있다.
인포믹스의 UNION은 대응되는 select 리스트의 자료형이 일치해야한다.
만약 그렇지 않을 경우 컬럼 리스트를 변경하거나 자료형을 바꿔야한다.
3.1.7 Order by, Group by
인포믹스에서는 ORDER BY절 또는 GROUP BY절에 사용하는 컬럼 리스트가 반드시 select리스트에 나타나야 한다.
3.1.8 Sorts
오라클에서의 NULL값을 가장 높은 값이고 인포믹스에서는 가장 낮은 값이다.
그러므로 오름차순으로 정렬을 할 경우 인포믹스에서는 NULL값이 먼저 출력된다.
이를 오라클과 동일한 순서로 변형시키기 위해서는 NULL값을 가장 높은 값으로 만들어 정렬할 수 있도록 stored procedure를 작성하고, 정렬이 끝나고 출력될 때 다시 NULL으로 교체하도록 하여야 한다.
3.1.9 Exceptions
하드 코딩된 오라클의 에러코드 값은 인포믹스의 에러 코드 값으로 교체해야한다.
3.1.10 Correlation Names
UPDATE나 DELETE의 메인 테이블에 대해 correlation name을 사용할 수 없다.
3.1.11 Aliases
테이블에 alias 를 주면 원본 테이블명을 select 리스트나 where절에서 사용할 수 없다.
3.1.12 Hierarchical Queries
인포믹스는 B-트리 형태의 계층적으로 구성된 질의 결과를 만들지 않는다.
오라클은 START WITH 와 CONNECT BY PRIOR 절을 사용하여 구현한다.
START WITH 는 루트 노드의 행을 지정하고, CONNECT BY에서 부모 노드와 자식 노드의 관계를 서술 한다. 이때 PRIOR 수식을 가장 먼저 확인한다.
다음 예는 JOB이 PRESIDENT인 직원을 루트 노드로 하여 그 아래 모든 하위 노드를 출력하는 질의어이다.
SELECT ename, empno, mgr, job FROM emp START WITH job = 'PRESIDENT' CONNECT BY PRIOR empno = mgr
오른쪽 테이블은 위의 질의 결과를 도식화하여 나타낸 것이다. 위와 같은 기능을 인포믹스에서 사용하려면 stored procedure나 function을 작성하여 cursor 또는 array를이용해야 한다. 인포믹스의 global array가 도움이 될 것이다.
3.2 호스트 변수 (Host Variables)
데이터 형에 따라 호스트 변수의 포맷을 변경할 필요가 있을 수 있다.
예를 들어 number나 date같은 자료형은 인포믹스에서 동일한 포맷으로 지원되지 않으므로 SQL문장안에서 포맷을 정의하는 절차를 거쳐야 한다.
예를들어 오라클 함수 TO_CHAR는 날짜와 숫자 값의 포맷을 사용한다.
비슷한 방식으로 인포믹스는 7.3 버전 이후 TO_DATE와 TO_CHAR 함수를 추가하였다.
또한 ESQL/C에서는 오라클의 날짜 포맷에 대응하여 인포믹스 날짜 포맷을 출력하는 ifx_to_gl_datetime() 함수를 가지고 있다.
위의 경우 포맷은 인포믹스에서 제공하는 값을 사용해야하며 오라클의 모든 포맷을 반 드시 포함하고 있는것은 아니다.
3.3 날짜 및 시간 함수 (Date and Time Functions )
현재 날짜를 처리하기 위하여 오라클은 SYSDATE를 사용하는데, 인포믹스에서는 다음과 같이 자료형에 따라 다르게 표현한다.
SQL문으로 현재 시스템 날짜를 얻기 위하여 SELECT DISTINCT TODAY FROM SYSTABLES
와 같이 사용한다. 또한 ESQL/COBOL의 ECO_TDY()함수나 ESQL/C의 rfmtdate()함수에서도 제공된다.
인포믹스의 날짜 처리 형태로 변환해야할 오라클 함수
· ADD_MONTHS(date,months),
· LAST_DAY(date)
· MONTHS_BETWEEN(date1, date2)
· NEW_TIME(date,current_timezone,new_timezone)
· NEXT_DAY(date,char)
· ROUND(date,format)
· SYSDATE
· TRUNC(date,format)
오라클의 TO_CHAR, TO_NUMBER, TO_DATE 함수에 대한 포맷은 다음 표를 참조한다.
3.3.1 number format
3.3.2 date format
3.3.3 RR format
RR 포맷을 YY 포맷과 유사하지만 서로 다른 세기(century)의 날짜값을 구분하기 위하여 사용한다
3.4 집계 함수 (Aggregagte Functions )
3.5 수학 함수 (Mathematical Functions )
인포믹스는 오라클의 수학함수 CEIL, FLOOR, SIGN, COSH, SINH, TANH를 지원하지 않는다. ROUND함수에서 round factor -32 에서 32까지의 값을 사용할 수 있다.
3.6 스트링 함수 (String Functions)
3.7 기타 오라클 함수
인포믹스는 다음과 같은 오라클 함수를 지원하지 않는다.
· CHARTOROWID
· CONVERT
· DUMP
· GREATEST
· GREATEST_LB
· HEXTORAW
· LEAST
· LEAST_UB
· RAWTOHEX
· ROWIDTOCHAR
· TO_LABEL
· TO_MULTI_BYTE
· TO_SINGLE_BYTE
· UID
· USER
· USERENV(OSDBA/ LABEL/ LANGUAGE/ TERMINAL/ SESSIONID/ ENTRYID)
· VSIZE
3.8 매크로(Macros)
인포믹스는 오라클의 macro를 지원하지 않으므로 코드에서 제거해야하고 관련된 로직은 인포믹스에서 동일하게 구현될 수 있다.
3.9 Pseudo-Columns
Pseudo-columns 은 테이블에는 존재하지만 SELECT * FROM table_name 과 같은 질의에서는 나타나지 않는 컬럼이다. 인포믹스에서 pseudo-column은 일반적으로 DBMS엔진에 의해 사용되므로 이러한 컬럼을 어플리케이션에서 직접적으로 사용하지 않는것이 향후 어플리케이션 이식성이나 어플리케이션 변경에 도움이 된다.
3.9.1 LEVEL
오라클에서 hierarchical query를 할때 pseudo-column LEVEL 은 루트노드에 대하여 1을 리턴하고 그 루트노드의 자식 노드는 2를 노드 2가 부모인 자식 노드는 3을 등등.. 이러한 형태로 출력된다.
질의에서 hierarchical 관계를 정의하려면 START WITH CONNECT BY 문을 사용한다.
인포믹스는 hierarchical 질의를 지원하지 않으므로 LEVEL 컬럼을 사용하지 않는다.
3.9.2 ROWID
오라클의 ROWID 컬럼은 각 데이터 행의 주소를 나타낸다.
출력되는 ROWID는 다음과 같은 정보를 가지고 있다.
· 데이터파일에서 데이터 블럭의 정보
· 데이터블럭에서의 행의 정보 (첫번째 행이 0)
· 데이터파일 정보 (첫번째 파일이 1)
대부분 데이터베이스에서 한 행을 나타내는 ROWID는 유일한 값을 가지지만 서로 다른 테이블에서 동일한 클러스터안에 저장된 행은 동일한 ROWID를 가진다.
ROWID 컬럼의 값은 오라클의 ROWID 자료형으로 저장된다.
ROWID는 새로 지워지고 새로 입력되면 새로운 값이 할당되므로 이 컬럼을 테이블의 primary key로 사용하지 말아야 한다. 또, ROWID 컬럼값은 입력,수정,삭제 될 수 없다.
SELECT ROWID, ename FROM emp WHERE deptno = 20
오라클의 ROWID는 인포믹스의 ROWID와 거의 동일하게 동작한다. 하지만 저장되는
자료형은 서로 다르다.
3.9.3 ROWNUM
오라클에서 ROWNUM 컬럼값은 선택된 결과 레코드의 순서를 나타낸다.
다음과 같은 질의는 첫번째 9개 행을 출력한다.
SELECT * FROM emp WHERE ROWNUM < 10
이런 ROWNUM을 이용하여 테이블의 각 행에 유일한 값을 할당할 수 있다.
UPDATE tabx SET col1 = ROWNUM
오라클은 각 행을 읽어온후 ROWNUM을 할당하고 ORDER BY절에 의해 정렬되므로 ORDER BY에 의한 순서와 ROWNUM 순서가 다를 수 있다. 그러나 ORDER BY절에 사용되는 컬럼이 인덱스를 사용한다면 순서가 같아진다. 다음과 같은 질의는 아무런 행도 리턴하지 않는다.
SELECT * FROM employee WHERE ROWNUM > 1
첫번째 행을 가져와서 ROWNUM을 1로 할당하므로 조건에 맞지 않아 출력되지 않는다.
두번째 행이 출력되기 위해서는 ROWNUM이 1로 다시 할당되는 이때도 조건에 맞지 않기 때문에 출력되지 않고 이후의 모든 행이 마찬가지 상태가 된다.
인포믹스는 ROWNU과 동일한 컬럼을 가지고 있지는 않지만 FIRST N 구문을 이용하여 구현할 수 있다.
인포믹스는 다음과 같은 복합적인 경우에는 사용할 수 없다.
· subqueries
· into temp 문
· view 정의
· stored procedure
· union 질의
ORDER BY 없이 FIRST N구문을 사용하면 의미없는 순서로 데이터가 출력될 것이다.
/* 월급이 가장 많은 10명을 출력 */
SELECT FIRST 10 name, salary FROM emp ORDER BY salary;
/* 10개의 최고 월급 출력 */
SELECT FIRST 10 DISTINCT salary FROM emp ORDER BY salary;
인포믹스 7.3은 "FIRST"란 이름으로 컬럼명을 사용할 수 있다. 따라서 "FIRST" 뒤에 양의 정수가 따라 오지 않는 경우는 테이블의 컬럼명으로 생각한다.
N값은 1에서 231 - 1 까지 사용할 수 있다.
UPDATE tabx SET col1 = ROWNUM
위와 같은 오라클의 ROWNUM을 할당하는 구문의 경우 ESQL/C 로 아래와 같이 구현한다.
int counter = 0; EXEC SQL declare c1 cursor for SELECT col1, col2 INTO :col1, :col2 FROM table 1 WHERE col1 = "XX"; EXEC SQL open c1; while (SQLCODE == 0) { EXEC SQL fetch c1; counter++; /* Increment counter for each row fetched */ if (counter >= 5) { break; /* logic... */ } /* End if */ } /* End while */
3.10 커서를 이용한 수정 (Update Using Cursors )
인포믹스와 오라클의 커서는 약간의 차이가 있다.
오라클과는 달리 인포믹스에서는 FOR UPDATE 커서가 여러 테이블을 조인하는 경우에는 사용할 수 없으므로 WHER CURRENT OF 문장을 테이블 조인상태에서 사용할 수 없다.
따라서 테이블을 조인해야할 경우는 동일한 커서 루프에서 WHERE CURRENT OF 문장을 제거하고 UPDATE문장을 분리하여야 한다.
인포믹스에서 commit 또는 rollback 문은 트랜잭션안에서오픈된 모든 커서를 닫는다.
커서를 닫지 않고 commit 또는 rollback을 실행하여야 할 경우 HOLD 커서를 선언할 수 있다. 그러나 HOLD커서는 FOR UPDATE 문에서 사용될 수 없다.
따라서 오라클에서 fetch 루프안에서 업데이트하거나 commit하는 어플리케이션은 인포믹스의 형태로 변환해야한다. 커서는 HOLD를 사용하여 선언하고 업데이트 문장은 WHERE CURRENT OF 문장 없이 사용한다. WHERE CURRENT OF 문장의 의미를 나타내기 위하여
WHERE ROWID = fetch된 rowid값 또는
WHERE primary key 컬럼 = fetch된 primary key 컬럼값
형태로 작성한다.
오라클의 트랜잭션 내의 fetch 루프를 구현하기 위하여 BEGIN WORK 문장이 COMMIT WORK 나 ROLLBACK WORK 문장에 바로 따라 올 수 있도록 한다.
3.11 시스템 테이블(System Tables )
오라클의 시스템 테이블 참조는 이에 대응되는 인포믹스의 시스템 카타로그 테이블 차조로 교체할 수 있다.
3.12 스토어드 프로시저 (Stored Procedures)
3.12.1 Size
인포믹스의 stored procedure는 대략 64K의 한계가 있다.
오라클의 64K가 넘는 procedure는 좀더 작은 단위로 쪼개고 필요한 매개변수와 리턴값을 서로 주고 받을 수 있도록 한다.
3.12.2 Packages
오라클의 stored function과 stored procedure는 인포믹스의 stored procedure로 교체할 수 있다. 그러나Package body는 stored procedure와 stored function의 그룹을 포함하고 있고 package는 stored procedure와 stored function의 리스트를 가지고 있다.
모든 package body는 인포믹스의 개별적인 stored procedure로 재작성해야 하고 package 레벨의 변수는 인포믹스의 global 변수로 대응시켜야 한다.
3.12.3 Exceptions
오라클은 CURSOR_ALREADY_OPEN, NO_DATA_FOUND, ZERO_DIVIDE 등과 같이 미리 정의되거나 사용자 정의된 exception label을 가지고 있다.
EXCEPTION 구조를 사용한 BEGIN/END 블럭에서 하나의 exception 만 허용되고 보통 END 문 바로 앞에 EXCEPTION 처리문이 위치 한다.
인포믹스 또한 미리 정의되거나 사용자가 정의한 exception을 지원하지만 표현 방식이 label형태가 아니고 숫자로 나타난다. 모든 exception은 stored procedure의 control block에서 체크되고, 각 control block의 상단부에 EXCEPTION문으로 명시적으로 선언해야한다.
오라클에서는 exception 처리가 global하게 처리된다.
인포믹스에서는 블럭단위로 exception처리가 제한된다.
3.12.4 Error Handling
SQLCA 구조체는 stored procedure에서 완벽하게 지원하지 않는다. SQLCODE 변수 체크는 불가능하다. 대신 DBINFO 함수를 사용해 sqlca.sqlerrd1과 sqlca.sqlerrd2 값을 추출해 낼 수 있다. 이 함수는 커서가 열린FOREACH 문안에서 사용될 수 있다.
3.12.5 Cursors
오라클의 global 커서는 인포믹스에서 temporary 테이블을 통하여 구현한다.
오라클 procedure에서는 커서를 명시적으로 선언하고 오픈하지만 인포믹스에서는 procedure안에서 명시적으로 커서를 선언할 필요 없다. 따라서 오라클의 procedure 커서는 인포믹스의 FOREACH 구조로 변환할 수 있다.
3.12.6 Flow Control
오라클에서는 GOTO 와 EXIT
'Informix > informix reference' 카테고리의 다른 글
informix version 확인 (0) | 2010.06.01 |
---|---|
ONBAR (0) | 2010.05.26 |
테이블을 특정 시점으로 복구하는 기능 (0) | 2010.05.24 |
[TIP] embedding SQL in UNIX Script (0) | 2009.12.29 |
DB size (0) | 2009.12.28 |