정보과학 IT

Oracle Pro*C 실무프로젝트 활용서 

물곰탱이 2013. 11. 26. 15:23

Oracle Pro*C 실무프로젝트 활용서

 

 

 

 

1장. Pro*C 소개와 기본 특징

  1-1. Pro*C 개요

  : SQL 문은 절차형 언어가 아니다. 그래서 오라클을 포함한 많은 데이터베이스는 PL/SQL이라는 절차형 언어를 제공한다. PL/SQL은 오라클 내부에서 실행되는 프로그램으로서 오라클 내부라는 한정된 공간에서 실행되는 도구이다. 다만 일반 프로그램 언어들과 다른 점이 있다면, Pro*C만으로는 실행 파일을 만들어 낼 수 없다는 것이다. 선행 컴파일러를 통해 생성된 C프로그램은 C 프로그램의 통상적인 방법으로 컴파일되고, 오라클 라이브러리와 결합(링크)되어 실행 모듈이 만들어진다.

 

 

  1-2. Pro*C 확장 범위

  : Pro*C는 오라클 데이터베이스와 연동할 수 있는 C 프로그램이다. Pro*C를 어느 범위까지 확장해서 활용할 수 있는지 요약하면 다음과 같다.

 

- 야간 혹은 주간 배치 프로그램

- 미들웨어 프로그램(Tuxedo, Tmax, Entera)

- OLTP 프로그램

· TCP/IP 모듈과 결합한 자료 생성 및 전송 프로그램(EDI) 

· 온라인 프로그램으로 이루어진 다량의 자료 가공 프로그램을 Pro*C로 이관하여 성능 개선

 

  1-3. 프로그램 작성 방식

(1) 내장 SQL 방식

  내장 SQL 방식이란 C 프로그램 내부에서 ‘EXEC SQL'이라는 접두사 뒤에 SQL 문장을 직접 기술하는

방식이다. 내장 SQL 방식은 통상적으로 가장 많이 사용된다. 우리에게 익숙한 윈도우 환경의 개발

툴과 비교해 본다면, OLE나 ODBC를 통해 데이터베이스와 연결하여 작업하는 방식의 프로그램과

비슷하다고 할 수 있다.

(2) OCI 방식

  OCI(Oracle Call Interface) 방식이란 OCI 라이브러리를 통해서 오라클 SQL 문장을 직접 호출하여

사용하는 방식이다. 내장 SQL 방식에 비해서 조금 더 하위 레벨에 해당하는 프로그래밍 방식으로서

OCI를 통해서 DB 핸들링 작업을 실행하기 때문에 데이터베이스 서버의 자원을 효율적으로 관리하고

SQL 문장 수행의 각 단계를 직접 제어할 수 있다는 장점이 있다.

 

 

  1-4. Pro*C의 데이터 형

● 기본적인 데이터 형의 일차원 배열

● CHAR 데이터 형과 VARCHAR 데이터 형의 이차원 배열

● 출력 호스트 변수로 VARCHAR 변수를 사용할 때 오라클은 구조체의 멤버 길이를 설정하지만 배열을 NULL-terminate(\0)시키지는 않습니다. 그러므로 출력하기 전에 출력 호스트 변수를 NULL-terminate 시키십시오. CHAR은 자동 NULL-terminate입니다.

● 기본적인 데이터 형에 대한 포인터

● 사용자 정의의 typedef

● 구조체

● 배열의 구조체

● 구조체에 대한 포인터 

● 구조체 배열

 

  오라클 데이터베이스에서 VARCHAR2 데이터 형의 선언은 가변 길이 문자열로, 데이터 형 선언 시 정의된 데이터 길이 내에서 다양한 길이의 데이터를 가질 수 있다는 것입니다. 좀더 쉽게 설명하자면 ‘VARCHAR2 CODE[40]'로 선언하고 ’1‘이라는 데이터를 할당하면 전체 40바이트의 길이 중 1바이트만 사용이 되고 나머지 39 바이트는 빈 공간으로 남게 되어 공간의 효율적 활용이 가능해지며 이러한 것을 가변 길이 문자열이라고 하는 것입니다.

 

 

2장. Pro*C 오류 진단과 처리

2-1. SQLCA

모든 Pro*C 프로그램에서 프로그램 실행에 관한 정보를 데이터베이스와 교환하기 위해서 SQLCA(SQL 통신영역)를 필수로 사용한다. SQLCA는 직전의 SQL 문장의 처리 결과에 대해 SQLCA 파일에 정의되어 있는 sqlca 구조체에 정보를 저장한다. 그러므로 개발자는 각 SQL 문장마다 SQLCA의 구조체 내용을 검색하여 에러와 경고 여부에 대한 정보를 확인할 수 있다.

 

 

2-2. ORACA

SQLCA 만으로도 많은 정보를 획득하고 필요한 작업을 처리할 수 있다. 실제 현업에서도 SQLCA 만을 참조하여 프로그램을 개발하는 경우가 많이 있다. 하지만 SQLCA 영역에서 얻는 정보보다 더 많읁 jd보를 획득하여 사용하고 싶다면 ORACA의 사용을 고려해 볼 수 있다.

ORACA는 SQLCA에서 얻을 수 있는 것 보다 조금 더 많은 정보를 얻을 수 있는 데이터 구조이며, ORACA는 실행 시 발생하는 에러뿐만이 아니라, 성능 통계에 대한 보조 정보도 제공한다.

ORACA는 다음과 같은 정보를 가지고 있다.

● 현재 SQL 문의 텍스트(orastxt)

● 에러가 있는 파일의 이름(orasfrm)

● 에러가 있는 행의 번호(oraslnr)

● SQL 문 보존 플래그(orastxtf): 이 플래그를 설정합으로써 어느 조건으로 문을 보존할 것인지를 선택할 수 있다.

● DEBUG 처리의 사용 허가 플래그: 이 플래그는 0이나 1을 설정할 수 있으며, 1을 설정한 경우에는 모든 DEBUG 처리를 사용할 수 있다. 

● 커서 캐시 검사(orahchf)

 

2-3. 오류 검출 및 처리

  오류 검출과 처리 방법에는 두 가지 방식이 있다. 하나는 명시적 오류 처리 방식이고, 다른 하나는 묵시적 오류 처리 방식이다. 명시적 오류 처리는 Pro*C 프로그램 안의 SQL 문장 또는 EXEC SQL 문장을 실행한 후에 매번 SQL 문장의 오류를 검사하고 이에 대한 처리를 기술하는 방식이다.

묵시적 오류 처리는 모든 SQL 문장과 EXEC SQL 문장 실행 후에 오류 처리를 기술하는 것이 아니라, 전역적 혹은 지역적으로 오류가 발생 했을 때의 처리 방안을 기술하여 모든 오류에 동일한 처리 방식을 적용 한다. 모든 오류 또는 경고에 대한 동일한 처리가 가능하며, 명시적 처리와 같이 매번 S삐 문장 마다 기술하는 방식이 아니기 때문에 개발자의 실수에 의한 누락이 발생하지는 않는다.

 

 (1) 명시적 오류 처리

명시적 오류 처리는 각 SQL 문장이 수행된 후에 SQLCA 구조체의 멤버인 ‘sqlcode'를 통해 확인 가능하며, 추출된 sqlcode 값에 따라 정상과 오류를 구분하여 처리한다. 오류가 발생한 경우 오류 번호가 아닌 오류 메시지 내용을 확인하고 싶다면 SQLCA 구조체의 또 다른 멤버인 ’sqlerrm.sqlerrmc'를 활용하면 된다.

 

 (2) 묵시적 오류 처리

묵시적 오류 처리에서는 전역적인 설정과 지역적인 설정이 모두 가능하다. 전역적으로 처리한다는 것은 프로그램의 시작 전, 즉 호스트 변수 선언 후에 기술하는 것을 의미한다. 지역적이라 함은 각 함수 별로 프로그램 시작 위치에 ‘EXEC SQL WHENEVER' 문장을 두는 것을 의미하며, 전역적 혹은 지역적 설정 두 방식 모두 실행 가능한 첫 번재 SQL 문장 이전에 선언하여 사용하게 된다.

 

3장. Pro*C 프로그램의 구성

 3-1. 어플리케이션 프롤로그

  (1). 선언 절 : 선언 절 Pro*C 프로그램에서 사용되는 모든 호스트 변수 및 지시자 변수 등을 선언하는

것을 의미한다.

 

 a. 호스트 변수 : SQL 문과 프로그램 문에서 모두 참조되어 사용되는 변수

호스트변수의 조건

◎ 선언 절에서 명시적으로 선언

◎ 선언한 대로 영문 대/소문자의 포맷대로 사용

◎ SQL 문장 안에서 사용할 때는 콜론(:)을 붙임

◎ C 문장에서는 콜론을 붙이지 않는다.

◎ SQL 예약어를 사용하면 안 된다.

 

 b. 표지변수 : VARCHAR과 같이 데이터 저장에 쓰이는 독특한 형태의 데이터 형뿐만 아니라

데이터베이스의 특정한 값을 표기하는 변수

 

표지변수의 조건

◎ 2바이트로 선언(short 형)

◎ NULL 값을 터리하고 SQL 문장 절단(truncation)을 발견하기 위해 사용

◎ NULL 값은 ‘1’로 표현. NULL 지정을 원치 않으면 값을 ‘0’으로 설정

◎ SQL 문장에서 지시자 변수 앞에 콜론을 붙이고 지시자 변수를 호스트 변수뒤에 붙임.

◎ 호스트 언어 문장에서는 표지 변수로만 사용 가능

 

 (2) INCLUDE 절 : 프로그램 안에서 사용될 함수, 선언문, 각종 ALIAS가 정리되어 있는 요약 파일

 

 (3) CONNECT 문 : DB 접속을 가능 하게 해주는 구문

 

 (4) 트랜잭션 제어 : DML 문장의 사용 후에는 트랜잭션을 제어해야 한다. 만약 트랜잭션에 대한 명시적인

제어를 하지 않고 종료할 경우에는 오라클 DBMS가 비정상 종료로 인지하고 데이터 갱신 작업에 대한

ROLLBACK를 실시한다.

 

※ 트랜잭션 제어 문장 구문

◎ EXEC SQL COMMIT [WORK][RELEASE];

◎ EXEC SQL ROLLBACK [WORK][RELEASE];

◎ EXEC SQL SAVEPOINT {point};

◎ EXEC SQL ROLLBACK TO SAVEPOINT {point};

 

 

4장. 컴파일 환경 구축

Pro*C를 이용하여 실행 파일을 만들기 위해서는 3단계의 과정을 거친다.

1) 오라클 Pre Complier를 이용하여 소스 프로그램을 생성한다 → 소스프로그램

2) Compiler(일반 3GL 언어 컴파일러를 사용하여 컴파일 한다 → 오브젝트 프로그램

3) Linker로 실행 가능한 프로그램을 생성한다.

 

  4-1. Pre 컴파일

  : Pro*C를 Pre Compilier라고 한다. Pro*C 컴파일러는 실행 파일을 만들어 주는 것이 아니라 실행 프로그램을 만들기 전의 단계에서 실행파일을 만들기 위한 준비를 해주는 역할을 수행한다.

 

  4-2. C 컴파일

  : C 컴파일은 두 단계로 이루어진다.

 

(1) cc -c 컴파일

cc -c xxx.c를 수행하면 c 소스가 컴파일되어 xxx.o라는 오브젝트 파일로 변환된다. 이는 C 프로그램이 시스템 라이브러리와 통신하여 프로그램을 수행할 수 있는 개별 오브젝트 파일로 변환해 주는 것이다.

 

(2) cc -o 컴파일

'cc -o 실행 파일명 xxx.o'를 수행하면 오브젝트 파일과 시스템 도는 사용자 정의 라이브러리 파일과 결합하여 사용자가 기술한 이름으로 실행 파일을 만들어 준다.

윈도우 환경으로 설명을 하자면 ODBC 또는 OLE DB를 통한 DB접속과 핸들링이 이루어지도록 프로그래밍을 한 후에 해당 오브젝트 (DLL)를 참조하지 않고 컴파일한 것과 동일한 개념이 된다.

(3) 쉘을 활용한 컴파일

 

 

5장. 단일 행 추출 프로그램

1단계 : INCLUDE 절 선언

2단계 : 호스트 변수 선언

3단계 : 메인 함수 부-DB 접속

4단계 : 메인 함수 부-SQL 문

 

 

6장. 다중 행 추출 프로그램

※ SELECT INTO와 DECLARE CURSOR의 차이

데이터가 1건이상이면 ‘ORA-2112' 에러가 발생한다

"PCC: SELECT..INTO returns too many rows"

추출될 데이터의 행을 명확하게 가늠하기 힘들 때에는 DECLARE CURSOR 프로그램으로 해야 하고 추출될 데이터를 명확히 알 수 있을 때는 SELECT INTO 프로그램을 사용하여야 한다.

 

  예를 들어, SELECT INTO 프로그램에서 데이터가 2건이 추출되어 에러가 발생한 경우에 INTO절에서 사용하는 변수를 1건 이상의 배열 값으로 선언하면 에러가 발생하지 않을 것이다. 즉 추출될 데이터 건수를 명확히 알 수 있는 경우라면 SELECT INTO로 프로그래밍하는 것이 가능하다. 주로 공지사항이나 게시판 등의 데이터를 추출할 경우에 사용이 가능하게 된다.

하지만 추출될 데이터를 명확히 알 수 없는 경우라면 DECLARE CURSOR 프로그램을 할 수 밖에 없다. 대부분의 경우가 이에 해당될 것이다. 그래서 SELECT INTO는 암시적 커서라고 하고 DECLARE CURSOR는 명시적 커서라고 하는 것이다.

 

다음은 다중 행 추출 프로그램 단계별 진행이다.

 

1단계 : INCLUDE 절 선언

2단계 : 호스트 변수 선언

3단계 : 메인 함수 부-DB 접속

4-1단계 : 메인 함수 부 1-커서 선언

4-2단계 : 메인 함수 부 2-커서 오픈

4-3단계 : 메인 함수 부 3-커서 FETCH

 

 

7장. Host Array를 이용한 다중 행 추출 프로그램

< Host array 를 이용한 다중행 추출 프로그램 >

 

=> 호스트 변수를 배열로 선언하면 여러건의 데이터를 배열의 수 만큼 한번에 가져올 수 있다.

=> 위의 두 경우는 한번에 한번의 데이터를 가져 온기 때문에 성능의 저하가 생긴다( 잦은 DBMS CALL )

=> sqlca.sqlerrd[2]

- 추출된 데이터 건수를 저장하고 있는 변수

- 이를 이용하면 추출된 데이터 만큼 데이터를 처리하는 것이 가능

- 현재 추출한 건수가 아니라 누적된 데이터 건수를 저장한다.

 

 

 

 

 

8장. Host Structure를 이용한 프로그램

< Host Structure 를 이용한 프로그램 >

 

struct{

int empno;

VARCHAR ename[20];

}DataSelect;

 

{생략}

 

EXEC SQL FETCH (커서명)

INTO :DataSelect;

 

=> 호스트 변수를 구조체로 선언 하였기 때문에, 데이터 FETCH 시에는 구조체명만 기술하며, 데이터 출력시에는 구조체.멤버 명으로 처리한다.

=> 만약 배열로 한번에 여러 개의 데이터를 처리 하고 싶다면, 구조체 멤버를 배열로 선언하면 된다.

 

  다중 행 추출 프로그램이라는 것이구나.. 실무에서 사용하면서 책에서 처음 말하는대로

SELECT INTO 와 DECLARE CURSOR의 차이점이 단지 단건이냐 다건이냐로 판단하고 추출 하는 줄 알았는데, 데이터 건수의 명확성으로 판단한다는 것을 알게 되었다.

 

 

9장. 프로그램 오류 처리

 9-1. ORA-1405 오류 처리

 

ORA-1403 : 추출될 데이터가 없거나 갱신할 데이터가 없어서 발생하는 오류

ORA-0001 : 중복된 데이터가 입력되어 발생하는 오류

ORA-1555 : SELECT중 읽고 있는 롤백 세그먼트의 이미지 클리어로 인한 오류

ORA-1405 : 추출된 데이터 중 NULL이 있기 때문에 발생하는 오류

 

 

9-2. Garbage 데이터 처리

Garbage 데이터 : 사용자가 의도하여 할당한 데이터나 정상적인 방법으로 추출된 데이터가 아니라 프로그램 오류에 의해 잘못 할당된 데이터를 의미

 

처리방법

(1) 오라클의 NVL 함수를 통해 NULL 데이터를 사용자 정의 값으로 치환하여 추출하는 방법

(2) 'memset'를 사용해서 해결하는 방법

 

<눈에 익은 오류 번호들이 줄줄이 보인다. 이중 가장 많이 봤던 오류는 ORA-1403 오류. 

초기화 하는 것이 memset인 줄은 알고 있었지만, 왜 memset를 사용하는지 알게되었다.>

 

 

10장. Dynamic SQL 프로그램

  10-1. 데이터 추출 프로그램

  10-2. 데이터 갱신 프로그램

 

<처음 개발할 땐 Static SQL이었다. 코딩자체가 Static SQL에 익숙해 졌었는데, 두 번째 사업구조개편 프로젝트를 하면서 소스들을 보니 Dynamic SQL 이었다. 모든 이해는 어렵지만, Static SQL과 Dynamic SQL의 차이와 사용 용도에 대해서도 알게 되었다. SQL 공부를 많이 해야겠다.>

 

 

11장. Procedure(PL/SQL) 호출 프로그램

  일반 SQL 문장은 ‘EXEC SQL' 접두어 뒤에 SQL 문장을 사용하였다. PL/SQL은 Sqlplus에서 사용하듯이 BEGIN과 END 사이에 기술하며, 앞뒤로 ’EXECUTE'와 ‘END-EXEC'를 사용하여 Procedure의 시작과 끝을 표기한다.

 

※ PL/SQL 호출

EXEC SQL EXECUTE

  BEGIN

    SP_GET_EMP;

  END;

END-EXEC;

 

  if(sqlca.sqlcode != 0){

    printf("SQLCODE : [%d].\n",sqlca.sqlcode);

  }   

 

12장. 실무 적용 프로그램

 

13장. Array precessing를 이용한 성능 향상

  • Array Processing 기능을 활용하면 한 번의 SQL 수행으로 다량의 로우를 동시에   
  •       insert/update/delete 할 수 있다.
  • 네트워크를 통한 데이터베이스 Call을 감소시켜주고, 궁극적으로 SQL 수행시간과 CPU 사용량을
  •       획기적으로 줄여준다.

     

     

    http://blog.daum.net/momnyymn/6