본문 바로가기

DataBase/Oracle

[Oracle] Pro*C - 간단정리

실무에서 사용하고 있는 Pro*C!

C의 확장자는. c이고, Pro*C의 확장자는. pc이다. 

Pro*C라는 건 일하게 되면서 처음 접하게 되었는데.. 

다음 프로젝트를 진행할때 참고할 수 있도록 제대로 정리를 해두어야겠다!

 

여러 사이트 정보를 참고하여 정리했지만, 틀린 정보일수 있음! > 틀린정보는 수정할예정!

 

 

Pro*C

Pro*C는 오라클 데이터베이스와 연동할 수 있는 C 프로그램이며, C 프로그램으로 처리할 수 있는 모든 기능을 Pro*C로도 구현할 수 있다

 

SQL 문은 절차형 언어가 아니기 때문에 오라클을 포함한 많은 데이터베이스는 PL/SQL이라는 절차형 언어를 제공한다. PL/SQL은 오라클 내부라는 한정된 공간에서 실행되는 도구인데, 이런 고민을 해결하기 위해서 대부분의 DBMS 벤더는 외부 C 프로그램과 결합할 수 있는 선행 컴파일러를 제공하고 있고, Pro*C는 오라클의 선행 컴파일러이다.


Pro*C는 혼자서  실행 파일을 만들어 낼 수없는 Pre Compiler(선행 컴파일러) 이다. 때문에 선행 컴파일을 통해서 실행 파일이 아닌 C 컴파일러가 인식할 수 있는 출력 파일 (확장자가 .c인 파일) 을 생성한다.
그렇게 생성된 C 프로그램은 C 프로그램의 통상적인 방법으로 컴파일된다.

 

 

기본 명령어

 

 

테이블 구조체 선언

EXEC SQL INCLUDE SQLCA.H

 

날짜 가져오기

char trans_dt[9]; // 날짜를 담을 변수
EXEC SQL SELECT TO_CHAR(SYSDATE-1, 'YYYYMMDD') INTO :trans_dt FROM DUAL

 

호스트 변수선언

  • Pro*C에서 SQL문에 placeholder로 사용한 Host 변수를 선언한다.
  • Pro*C 컴파일시 옵션 MODE=ORACLE 을 추가하면 DECLARE SECTION 없이 host 변수를 선언할 수 있다.
  • 이때 이 데이터타입은 테이블을 정의할 때 사용되는 Oracle 데이터 타입과 일치할 필요는 없다.

 

호스트 변수의 조건

  • 선언절에서 명시적으로 선언한다.
  • SQL문 앞에 콜론 (:)을 붙인다.
  • C문에서는 콜론을 붙이지 않는다.
  • SQL예약어를 사용할 수없다.

 

호스트변수 사용 예시 - SELECT (단건 조회)

EXEC SQL BEGIN DECLARE SECTION;
int bnk_cd;
char bnk_nm[10];
EXEC SQL END DECLARE SECTION;

EXEC SQL SELECT BNK_CD
                ,BNK_NM
         INTO :bnk_cd, :bnk_nm
FROM TM_BNK;

 

 

CURSOR 와 FETCH

 

CURSOR 와 FETCH 

  • CURSOR : SELECT 문을 통한 결괏값들을 저장할 저장할 메모리 공간. 모든 SQL문은 커서를 소유한다.
  • FETCH : 커서에서 원하는 결과값을 추출하는 것

 

CURSOR 

  • 복수의 튜플들에 접근하는것이 가능하다. (단일 행은 into 절을 이용하여 변수에 저장하여 처리할 수 있다.)
  • 첫 번째 튜플에 대한 포인터로 생각할 수 있다.
  • 질의 결과로 반환되는 튜플들을 한 번에 하나씩 차례대로 처리할 수 있다.
  • 단점 : 많은 데이터를 처리할 경우, SQL 의 성능을 떨어뜨린다.

 

CURSOR 명령어

  • DECLARE : 커서를 정의한다. 
  • OPEN : 커서를 연다.  커서안의 검색이 실행된다. 아무런 데이터행을 추출하지 못해도 에러가 발생하진 않는다.
  • FETCH : 현재 데이터 행을 OUTPUT 변수에 반환하여 한 라인씩 데이터를 FETCH 한다.
                   select 문의 컬럼의 수와, output 변수의 수가 동일해야 한다.
  • CLOSE : 사용을 마친 커서는 반드시 닫아주어야 한다.
 

CURSOR이용

char buf[500]; // 쿼리를 저장할 변수

EXEC SQL PREPARE statement FROM buf; // 쿼리하고자 하는 sql문장 정의
EXEC SQL DECLARE cursor_name CURSOR FOR statement; // 사용할 커서 선언 
EXEC SQL OPEN cursor_name; // 선언한 커서 오픈         
EXEC SQL FETCH cursor_name INTO :host_variable1, :host_variable2, :host_variable3, ....; // 열어둔 커서 실행
EXEC SQL CLOSE cursor_name; // 열었던 커서 닫음

 

- 예시

EXEC SQL INCLUDE SQLCA.H

EXEC SQL BEGIN DECLARE SECTION;
// 변수 선언
EXEC SQL END DECLARE SECTION;

char buf[QUERY_LENGTH];

// Query 세팅
sprintf(buf, 쿼리 ,TABLE_NAME);         

EXEC SQL PREPARE PRE_TABLE_NAME FROM :buf;
EXEC SQL DECLARE RES_TABLE_NAME CURSOR FOR PRE_TABLE_NAME;
EXEC SQL OPEN RES_TABLE_NAME;

 

커서 닫기

EXEC SQL CLOSE cur_data;
  • 커서는 열었다면 반드시 닫아주어야 한다.

 

 

단건조회와 대량처리

 

단건조회

EXEC SQL BEGIN DECLARE SECTION;

VARCHAR uid[80];	
CHAR name[10];
CHAR job[32];
INT age;

EXEC SQL END DECLARE SECTION;

    ......

    EXEC SQL SELECT NAME, JOB, AGE 
    INTO :name, :job, :age
    FROM PERSON
    WHERE UID = :uid;

    if(sqlca.sqlcode != 0) {  // 오류일경우
        if(sqlca.sqlcode == 1403) {  
            // 조건에 맞는 데이터가 없는경우
            return 0;
        } else {
        	//에러 메세지 출력
            fprintf(stderr, "%.*s\n", sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc);
            return -1;
        }
    }

 

커서 FETCH - 대량처리

char buf[1024]; // 여러 건을 동시에 커리하여 DB의 데이터를 배열 형태로 가져오기 위한 변수.
EXEC SCL FETCH cur_data INTO :buf;
  • while문으로 반복하여 사용한다. 
EXEC SQL BEGIN DECLARE SECTION;

VARCHAR uid[80];	
CHAR name[10];
CHAR job[32];
INT age;

EXEC SQL END DECLARE SECTION;

    ......

    EXEC SQL  AT :db_con1  DECLARE emp_cursor CURSOR FOR
    SELECT NAME, JOB, AGE 
    FROM PERSON
    WHERE UID = :uid;

    EXEC SQL OPEN emp_cursor;

    if(sqlca.sqlcode != 0) {
        fprintf(stderr, "CURSOR OPEN ERROR: %.*s\n", sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc);
        return -1;
    }

    while(1) {
        EXEC SQL FETCH emp_cursor
        INTO :name, :job, :age;

        if(sqlca.sqlcode != 0) {  // 오류일경우
            if(sqlca.sqlcode == 1403) {  
                // 조건에 맞는 데이터가 없는경우
                return 0;
            } else {
                //에러 메세지 출력
                fprintf(stderr, "%.*s\n", sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc);
                return -1;
            }
        }
        
        printf("NAME: %s \t JOB: %ld \t AGE: %f\n", name, job, age);
    }

 

 

sqlca.sqlcode

sqlca.sqlcode 의미
 sqlca.sqlcode == 0   정상 처리
 sqlca.sqlcode == 1403  조회된 데이터가 없다
 sqlca.sqlcode == 100  insert 된 데이터가 없다
 sqlca.sqlcode < 0  오류 

 

sqlca.sqlerrd

sqlca.sqlerrd 의미
 sqlca.sqlerrd[2]  select 조회 건수
 fetch 누적 조회 건수
 insert, update, delete 건수 를 리턴
 sqlca.sqlerrd[4]  sql문 오류가 발생한 위치 를 리턴

 

sqlca.sqlerrm

sqlca.sqlerrm 의미
sqlca.sqlerrm.sqlerrml 오류메시지의 길이
sqlca.sqlerrm.sqlerrmc에 저장된 문자열의 길이
sqlca.sqlerrm.sqlerrmc 오류메시지 내용.
오류메시지는 Null terminate 문자열이 아니므로 반드시 sqlca.sqlerrm.sqlerrml로 크기를 체크해야 한다.

 

 

오류처리

 

EXEC SQL WHENEVER ~를 이용한 오류 처리 

EXEC SQL WHENEVER <condition> <action>; 
  •  <condition> : Event 종류 상수로 SQLWARNING, SQLERROR, NOT FOUND 등이 있다.
  •  <action> : Event에 대한 처리 방법
EXEC SQL WHENEVER NOT FOUND CONTINUE;
  • 데이터가 없다고 하더라도 계속해서 작업을 진행하라는 의미이다.

 

 

문자열 저장, 출력 함수

 

printf(), fprintf(), sprintf()의 차이

함수 의미 출력 위치
printf(서식문자열, 인자1 ....인자N) 인자값을
포맷 스트링으로
표준출력한다
화면 (console)
fprintf(파일, 서식문자열, 인자1 ...인자N) 지정한 파일 (file)
sprintf(버퍼, 서식문자열, 인자1 ... 인자N) 지정한 버퍼(buf)

 

printf("%.*s", parameter1, parameter2);
  • parameter1으로 지정한 길이만큼 parameter2 문자열을 출력

 

 

 

 

 

+ 추가

 

Fetch ~ into

EXEC SQL DECLEAR cur_resel_org CURSOR FOR
SELECT BNK_CD
      ,BNK_NM
FROM TM_BNK;

의 경우

EXEC SQL FETCH cur_resel_org
         INTO :bnk_cd
             ,:bnk_nm;

으로 받을 수 있다.

 

 

 

 

 


IT 개발자 Note :: Pro*C 6. 대량처리 (배열처리) (it-note.kr)

 

Pro*C 6. 대량처리 (배열처리)

배열처리 (Host Arrays) 배열로 처리하는 것의 장점 Host 변수에 배열을 넘긴다는 것은 한번에 여러건을 동시에 처리한다는 의미입니다. 여러건을 동시에 처리하는 것의 장점은 DBMS와의 통신 횟수를

www.it-note.kr

랄라라 :: [번역] 런타임 에러 처리 (Handling Runtime Errors) (tistory.com)

 

[번역] 런타임 에러 처리 (Handling Runtime Errors)

목 차 ▣ The Need for Error Handling ▣ Error Handling Alternatives ▣ SQLSTATE 상태변수( The SQLSTATE Status Variable ) ▣ SQLCODE선언( Declaring SQLCODE ) ▣ Key Components of Error Reporting Usin..

unabated.tistory.com

C - C언어 함수 printf, fprintf, sprintf 의 차이점 알아보기 : 네이버 블로그 (naver.com)

 

C - C언어 함수 printf, fprintf, sprintf 의 차이점 알아보기

화면, 파일, 버퍼로 구분해서 출력하기 printf(), frpintf(), sprintf() printf() 로 부터 파생된 두 개의 ...

blog.naver.com

pro*c 란 - 초보자를 위한 개념 설명 (tistory.com)

 

pro*c 란 - 초보자를 위한 개념 설명

이글은 초보자를 위한 것으로 Pro*C란 무엇인가를 설명해 놓은 것일 뿐입니다. 그냥 참조만 하시기 바랍니다. 원본 출처 : http://home.bcline.com/hoya1/ 1.1 Pro*C란? ORACLE RDBMS에 준비된 Pro*C툴은, SQL문을..

kikook.tistory.com

Oracle Pro*C 실무 프로젝트 활용서_2 - 하루에 하나씩 (itshinestar.co.kr)

 

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

[ 알고가야 할 개념 ] 1. CURSOR 와 FETCH ? - SELECT 문을 통해 결과값들이 나올 때 이 결과들을 메모리 공간에 저장하게 되는데, 이 메모리 공간을 ' 커서 ' 라고 합니다. 모든 SQL 문은 커서 소유 - 커서

itshinestar.co.kr

https://lazyjin.tistory.com/entry/ProC01

 

ProC 에서 CURSOR 사용하기

Dynamic SQL이라고 함. 자세한건 생략하고 예문들어감. 요런 기본틀이 있다....라는거다. EXEC SQL BEGIN DECLARE SECTION; char strStmt[QUERY_LENGTH]; EXEC SQL END DECLARE SECTION;    INICHAR(strStmt); /..

lazyjin.tistory.com

https://blocked.tistory.com/396

 

[ORACLE] Pro*C 간단 매뉴얼

Pro-C 간단 매뉴얼 --------------- 2000. 5. 23 --------------- +++++++++++ ProC... +++++++++++ -. 오라클 데이타베이스 내의 테이블에 존재하는 레코드들을 조회,수정 등의 데이타 처리를 하고, C프로그램으..

blocked.tistory.com

https://jink1982.tistory.com/110 

 

[Pro*c] sqlca 구조체 설명 ( 오류 처리 )

Sqlca 구조체 설명 및 오류 처리 Pro*c에서 쿼리를 실행 할 때 마다 sqlca로 결과를 전달 해 준다. 그래서 sqlca의 구조체를 이해해야 오류 발생시 적절하게 조치 하는데 필요하다. Sqlca 알아보기 아

jink1982.tistory.com

https://snowinblue.tistory.com/9

 

C, C++ printf 포맷에서 .*s의 의미

printf("%.*s", parameter1, parameter2); 위와 같은 형태로 printf가 사용되는 경우가 있다. parameter1으로 지정한 길이만큼 parameter2 문자열을 출력한다는 의미이다. (참고: https://stackoverflow.com/ques..

snowinblue.tistory.com

https://kikook.tistory.com/499

 

pro*c 란 - 초보자를 위한 개념 설명

이글은 초보자를 위한 것으로 Pro*C란 무엇인가를 설명해 놓은 것일 뿐입니다. 그냥 참조만 하시기 바랍니다. 원본 출처 : http://home.bcline.com/hoya1/ 1.1 Pro*C란? ORACLE RDBMS에 준비된 Pro*C툴은, SQL문을..

kikook.tistory.com

https://12bme.tistory.com/247

 

[Pro*C] Pro*C 소개와 기본 특징 및 오류 진단

1. Pro*C 소개와 기본 특징 1-1. Pro*C 개요 SQL 문은 절차형 언어가 아닙니다. 그래서 오라클을 포함한 많은 데이터베이스는 PL/SQL이라는 절차형 언어를 제공합니다. PL/SQL은 오라클 내부에서 실행되는

12bme.tistory.com