본문 바로가기

Pro*C

[Pro*C 오라클 DB] Pro*C 프로그램 구성과 DB접속

 

Pro*C

 


 

  • Pro*C 프로그램은 큰 맥락에서 2개 부분으로 구성 되어있다.
    1. 어플리케이션 프롤로그
          ㄴ> 변수를 정의하고 Pro*C 프로그램을 위한 일반적인 준비수행

    2. 어플리케이션 본체
            ㄴ> ORACLE 데이터를 조작하기 위한 쿼리문을 포함
                   Pro*C가 처리할 때 필요로 하는 코드의 앞뒤에 C코드 지정 가능

 

어플리케이션 프롤로그

1. 선언절

  • Pro*C 프로그램에서 사용 되는 모든 호스트 변수 및 지시자 변수의 선언을 의미
  • 외부 선언은 전역, 내부 선언은 지역적으로 사용함

 

1-1. 호스트 변수

  • Pro*C에서 사용하는 변수 중에서 SQL 문과 프로그램 문에서 모두 참조되어 사용되는 변수
  • 데이터 형은 선언 절에서 Pro*C 의 호스트 언어를 사용해서 선언되어야함

호스트 변수의 선언 방식

EXEC SQL BEGIN EDCLARE SECTION;
    VARCHAR uid[20];
    VARCHAR pwd[20];
EXEC SQL END EDCLARE SECTION;

 

EXEC SQL BEGIN EDCLARE SECTION;

의 사이에서 이루어지며

C의 모든 데이터형을 사용 할 수 있다.

EXEC SQL END EDCLARE SECTION;

 

 

EXEC SQL 문장 안에서는 변수 앞에 클론 (:) 을 붙여서 사용 하면된다.

호스트 변수 사용 방법 예제

#include <stdio.h>
#include <sqlca.h>

EXEC SQL BEGIN DECLARE SECTION;
    VARCHAR uid[20];
    VARCHAR pwd[20];
EXEC SQL END DECLARE SECTION;


void main() {

... 중략

EXEC SQL SELECT empno
            INTO: empno /* 호스트 변수 사용 */
            FROM scott.emp
            WHERE rownum = 1;

printf("EMPNO : [%d].\n", empno); /* C프로그램 내 호스트 변수 사용 */

}

 

조건 정리

  • 선언 절에서 명시적으로 선언
  • 선언한 대로 영문 대/소문자 포멧 사용
  • SQL 문장 안에서 사용할 땐 클론 (:) 을 붙임\
  • C 문장에서는 클론을 붙이지 않음
  • SQL 예약어 사용 금지

 

1-2. 표지 변수

 

  • 다양햔 형태의 변수를 지원하는 VARCHAR 데이터형
  • VARCHAR 와 같이 데이터 저장에 쓰이는 독특한 형태의 데이터,DB의 특정한 값을 표기하는 변수를 표지 변수라고함
  • DB만 갖고 있는 NULL 이라는 값을 구분지을 수 있는 독특한 형태의 변수
  • 호스트 변수에 1:1 로 대응해 NULL인지 아닌지 확인하는 변수
  • DB에 임의로 NULL 을 할당하려고 할 때도 사용된다

 

표지변수 조건

  • 2바이트로 선언한다 (short 형)
  • NULL 값을 처리하고 SQL 문장 절단을 발견하기 위해 사용된다.
  • NULL 값은 -1 로 나타내고 NULL 지정을 원치 않으면 값을 0 으로 설정한다
  • SQL 문장에서 지시자 변수 앞에 클론을 붙이고 지시자 변수를 호스트 변수 뒤에 붙임
    ex) 호스트 변수 : 지시자 변수
  • 호스트 언어 문장에서는ㅌ 표지 변수로만 사용이 가능하다
    호스트 변수처럼 데이터 값을 획득하는 변수로 사용할 수 없다.

호스트 변수 선언 부에 short 형 으로 선언한 표지 변수를 데이터 추출 시
데이터 추출 구문에서 호스트 변수와 1:1로 선언하면 추출된 데이터의 값이 NULL인지 아닌지 명확하게 표기가능

혹은 ALIAS 를 통해 사용하는 방식이 있음

 

호스트 변수와 지시자변수 를 1:1 연결사용 예제

#include <stdio.h>
#include <sqlca.h>

EXEC SQL BEGIN DECLARE SECTION;
        VARCHAR uid[20];
        VARCHAR pwd[20];
        int empno;
        short i_empno;
EXEC SQL END DECLARE SECTION;

void main() {

... 중략 

EXEC SQL SELECT empno
        INTO:empno:i_empno /* 호스트 변수 & 지시자 변수 사용 */
        FROM scott.emp
        WHERE rownum =1;
        
/* C프로그램 내의 호스트 변수 사용 */
printf("EMPNO : [%d], EMP INDICATOR : [%d]. \n" , empno, i_empno);
}

 

 

INDICATOR ALIAS  사용 예제

#include <stdio.h>
#include <sqlca.h>

EXEC SQL BEGIN DECLARE SECTION;
        VARCHAR uid[20];
        VARCHAR pwd[20];
        int empno;
        short i_empno;
EXEC SQL END DECLARE SECTION;

void main() {

... 중략 

EXEC SQL SELECT empno
        INTO:empno INDICATOR : i_empno /* 호스트 변수 & 지시자 변수 사용 */
        FROM scott.emp
        WHERE rownum =1;
        
/* C프로그램 내의 호스트 변수 사용 */
printf("EMPNO : [%d], EMP INDICATOR : [%d]. \n" , empno, i_empno);
}

INDICATOR 라는 ALIAS 를 통해 표지 변수 사용
이 프로그램을 실행하면 1:1 로 매치되는 변수의 추출된 데이터 값이 NULL 이면 -1 아니면 0이 출력된다

 

 

SELCET 문장이 아닌 DML(INSERT, UPDATE, DELETE)에서 호스트 변수에 NULL 할당 후 데이터 갱신 프로그램

#include <stdio.h>
#include <sqlca.h>

EXEC SQL BEGIN DECLARE SECTION;
        VARCAHR uid[20];
        VARCAHR pwd[20];
        int empno;
        short i_empno;
EXEC SQL END DECLARE SECTION;

void main() {

... 중략

/* 사원 번호 컬럼에 NULL 을 삽입하기 위한 표지 변수 설정 */ 
i_empno = -1;

EXEC SQL INSERT INTO emp VALUES(:empno:i_empno);

}

표지변수 i_empno 에 -1을 넣어
empno 변수에 NULL 할당

 

 

2. INCLUDE 절

프로그램 안에서 사용 될 함수, 선언문, ALIAS 가 정리되어있는 요약 파일

 

3.CONNECT 문

DB핸들링 프로그램에 가장 기본적인 부분인 접속부분

 

3-1 지역 DB 접속 예제

#include <stdio.h>
#include <sqlca.h>

EXEC SQL BEGIN DECLARE SECTION;
    char username[20] = "oracle";        // 사용자명
    char password[20] = "oraclepassword";  // 비밀번호
    char dbname[20] = "localhost:1521/ORCL"; // DB 주소 (로컬에서 연결)
EXEC SQL END DECLARE SECTION;

int main() {
    /* DB 접속 */
    EXEC SQL CONNECT :username IDENTIFIED BY :password USING :dbname;
    
    if (sqlca.sqlcode != 0) {
        printf("DB 접속 실패\n");
        return -1;
    }
    
    printf("DB 접속 성공\n");

    /* SQL 처리 예시 */
    EXEC SQL SELECT emp_id, emp_name, salary INTO :emp_id, :emp_name, :salary FROM employees WHERE emp_id = 1;
    
    printf("사원 번호: %d\n", emp_id);
    printf("사원 이름: %s\n", emp_name);
    printf("급여: %f\n", salary);

    /* DB 접속 해제 */
    EXEC SQL COMMIT WORK;  // 변경사항 커밋
    EXEC SQL DISCONNECT;   // DB 연결 해제
    
    return 0;
}

 

3-2. 원격 DB접속

1. 원격 DB서버 정보 확보

2. TNS 설정
    - tnsnames.ora 파일을 수정하여 원격 DB 정보를 등록합니다.

    -tnsnames.ora 파일은 기본적으로 $ORACLE_HOME/network/admin/ 디렉토리에 있습니다.

REMOTE_DB =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = db.example.com)(PORT = 1521))
    (CONNECT_DATA =
      (SERVICE_NAME = ORCL)
    )
  )
  
REMOTE_DB는 TNS 서비스 이름이며, 나중에 접속 시 사용
HOST는 원격 데이터베이스 서버의 주소
PORT는 데이터베이스 서버의 포트 번호
SERVICE_NAME은 데이터베이스 서비스 이름

 

 

 

4. 트랜잭션 제어

오라클은 기본적으로 트랜잭션을 명시적으로 제어한다.

모든 DML 문장의 수행 후에 자동 COMMIT, ROLLBACK가 아닌 사용자가 해야한다는 것임

EXEC SQL COMMIT [WORK] [RELEASE]

EXEC SQL ROLLBACK [WORK] [RELEASE]
 
EXEC SQL SAVEPOINT {point};

EXEC SQL ROLLBACK TO SAVEPOINT {point};

 

EXEC SQL COMMIT,ROLLBACK [WORK] [RELEASE]

  • 데이터의 영구적인 갱신을 위해서는 EXEC SQL COMMIT WORK 문장을 사용
  • 원형으로 복구하기 위해 EXEC SQL ROLLBACK WORK 문장을 사용
  • 이때 트랜잭션의 제어 후 DB와 접속을 헤제하기 위해선 RELEASE 문을 붙여 사용한다

EXEC SQL SAVEPOINT {point};

EXEC SQL ROLLBACK TO SAVEPOINT {point};

 

여러 DML이 있으면 특정 DML 이 실패할 경우에 전체를 롤백할지 특정부분까지 롤백할지 결정해야함

단순하게 롤백은 전체만 지원하기 떄문에 특정부분까지 롤백하기 위해서는 SAVEPOINT 를 사용해야함