본문 바로가기

카테고리 없음

[Pro*C 오라클 DB] 단일 행 추출 프로그램

 

Pro*C

 


 

Pro*C 파일 (single_row.pc)

/* single_row.pc: Pro*C를 이용한 단일 행 추출 프로그램 */
#include <stdio.h>
#include <sqlca.h>

/* 데이터베이스 연결 정보 선언 */
EXEC SQL BEGIN DECLARE SECTION;
char username[20] = "scott";          /* 사용자 이름 */
char password[20] = "tiger";          /* 비밀번호 */
int employee_id = 100;                /* 검색할 직원 ID */
char employee_name[50];               /* 직원 이름 결과 저장 */
EXEC SQL END DECLARE SECTION;

/* 에러 처리 함수 */
void check_sql_error() {
    if (sqlca.sqlcode < 0) {
        printf("SQL 에러: %s\n", sqlca.sqlerrm.sqlerrmc);
        EXEC SQL ROLLBACK WORK RELEASE;
        exit(1);
    }
}

int main() {
    /* 데이터베이스 연결 */
    EXEC SQL CONNECT :username IDENTIFIED BY :password;
    check_sql_error();
    printf("데이터베이스 연결 성공\n");

    /* 단일 행 추출 SQL */
    EXEC SQL SELECT ename
             INTO :employee_name
             FROM emp
             WHERE empno = :employee_id;
    check_sql_error();

    /* 결과 출력 */
    printf("직원 이름: %s\n", employee_name);

    /* 데이터베이스 연결 해제 */
    EXEC SQL COMMIT WORK RELEASE;
    printf("데이터베이스 연결 종료\n");

    return 0;
}

 

  • EXEC SQL BEGIN DECLARE SECTION
    • SQL 변수들을 선언하는 섹션
    • username, password는 데이터베이스 연결에 사용
    • employee_id는 검색 조건, employee_name은 결과를 저장
  • EXEC SQL CONNECT
    • 데이터베이스 연결을 설정
  • EXEC SQL SELECT
    • SQL SELECT 문을 사용하여 emp 테이블에서 단일 행 데이터를 가져옴
    • empno = :employee_id 조건에 따라 ename 필드 값을 가져와 employee_name에 저장
  • check_sql_error()
    • SQL 실행 결과를 확인하고 에러가 발생하면 처리
  • EXEC SQL COMMIT WORK RELEASE
    • 데이터베이스 연결을 종료

 

컴파일 과정

Pro*C를 사용해 C 파일로 변환
다음 명령을 사용하여 .pc 파일을 .c 파일로 변환

proc iname=single_row.pc oname=single_row.c include=$(ORACLE_HOME)/precomp/public

 

 

C 파일 컴파일
변환된 .c 파일을 컴파일하여 실행 파일을 생성

gcc -o single_row single_row.c -I$(ORACLE_HOME)/precomp/public -L$(ORACLE_HOME)/lib -lclntsh

 

실행

./single_row

 

예상 출력
만약 emp 테이블에 직원 번호(empno)가 100인 데이터가 있다면:

결과

더보기

데이터베이스 연결 성공
직원 이름: SMITH
데이터베이스 연결 종료

 

 


DB에서 이름, 전화번호, 나이, 성별 을 가져오는 프로그램

/* 1. 필요한 헤더 파일 포함 */
#include <stdio.h>         // 입출력 함수 사용을 위한 표준 라이브러리
#include <string.h>        // 문자열 조작 함수 사용
#include <sqlca.h>         // Pro*C에서 사용하는 SQLCA 구조체 정의

/* 2. VARCHAR 정의: Pro*C는 VARCHAR 구조체를 사용 */
VARCHAR name[50];          // 이름 저장 (최대 50자)
VARCHAR phone[20];         // 전화번호 저장 (최대 20자)
VARCHAR age[5];            // 나이 저장 (최대 5자)
VARCHAR gender[10];        // 성별 저장 (최대 10자)

/* 3. 메인 함수 시작 */
int main() {
    /* 3-1. 사용자 ID와 비밀번호 초기화 */
    VARCHAR uid[30];       // 사용자 ID 저장
    VARCHAR pwd[30];       // 비밀번호 저장

    strcpy((char*)uid.arr, "userid");         // 사용자 ID를 배열에 복사
    uid.len = (short)strlen((char*)uid.arr);  // 문자열 길이를 설정

    strcpy((char*)pwd.arr, "password");       // 비밀번호를 배열에 복사
    pwd.len = (short)strlen((char*)pwd.arr);  // 문자열 길이를 설정

    /* 3-2. 데이터베이스 연결 */
    EXEC SQL CONNECT :uid IDENTIFIED BY :pwd;
    if (sqlca.sqlcode != 0) {  // 연결 실패 시 에러 처리
        printf("데이터베이스 연결 실패: %s\n", sqlca.sqlerrm.sqlerrmc);
        return 1;
    }
    printf("데이터베이스 연결 성공!\n");

    /* 3-3. SQL 명령문 선언 */
    EXEC SQL DECLARE cur CURSOR FOR
        SELECT name, phone, age, gender  /* 가져올 컬럼들 */
        FROM table_name                  /* 테이블 이름 */
        WHERE rownum = 1;                /* 한 행만 선택 첫번 째 행만 가져옴 */

    /* 3-4. 커서 열기 */
    EXEC SQL OPEN cur;
    if (sqlca.sqlcode != 0) {  // 커서 열기 실패 시 에러 처리
        printf("커서 열기 실패: %s\n", sqlca.sqlerrm.sqlerrmc);
        return 1;
    }

    /* 3-5. 한 행 데이터를 가져오기 */
    EXEC SQL FETCH cur INTO :name, :phone, :age, :gender;
    if (sqlca.sqlcode == 1403) {  // 데이터가 없는 경우
        printf("데이터가 없습니다.\n");
    } else if (sqlca.sqlcode != 0) {  // 기타 에러 발생 시
        printf("데이터 가져오기 실패: %s\n", sqlca.sqlerrm.sqlerrmc);
    } else {
        /* 데이터 출력 */
        name.arr[name.len] = '\0';       // 널 문자로 문자열 종료
        phone.arr[phone.len] = '\0';     // 전화번호 문자열 종료
        age.arr[age.len] = '\0';         // 나이 문자열 종료
        gender.arr[gender.len] = '\0';   // 성별 문자열 종료

        printf("가져온 데이터:\n");
        printf("이름: %s\n", name.arr);
        printf("전화번호: %s\n", phone.arr);
        printf("나이: %s\n", age.arr);
        printf("성별: %s\n", gender.arr);
    }

    /* 3-6. 커서 닫기 */
    EXEC SQL CLOSE cur;

    /* 3-7. 데이터베이스 연결 해제 */
    EXEC SQL COMMIT WORK RELEASE;

    printf("프로그램 종료.\n");
    return 0;
}

 

실행 결과 예시

데이터베이스에 다음 데이터가 있다고 가정

김철수 010-1234-5678 30 남성

 

데이터베이스 연결 성공!
가져온 데이터:
이름: 김철수
전화번호: 010-1234-5678
나이: 30
성별: 남성
프로그램 종료.

 

 

1. EXEC SQL CONNECT

  • 용도: 데이터베이스에 연결하는 구문입니다.
  • 설명: CONNECT 구문은 Oracle 데이터베이스에 연결할 때 사용됩니다. Pro*C 프로그램에서 사용자 ID와 비밀번호를 사용하여 데이터베이스에 접속을 시도
EXEC SQL CONNECT :uid IDENTIFIED BY :pwd;

 

  • **:uid**와 **:pwd**는 변수 해당 변수에 저장된 사용자 이름과 비밀번호로 데이터베이스에 연결
  • 연결이 성공하면 이후 SQL 문을 실행할 수 있다. 만약 연결이 실패하면 오류가 발생

예시:

EXEC SQL CONNECT user_id IDENTIFIED BY password;

 

 

2. EXEC SQL DECLARE

  • 용도: 커서(Cursor)를 선언하는 구문
  • 설명: DECLARE 구문은 SQL 커서를 선언하여 SQL 쿼리 결과를 순차적으로 처리할 때 사용
EXEC SQL DECLARE cur CURSOR FOR
    SELECT name, phone, age, gender
    FROM table_name
    WHERE rownum = 1;

 

 

  • **cur**는 커서의 이름입니다. 이 커서를 사용하여 SQL 쿼리를 실행하고 결과를 처리
  • SELECT 쿼리를 사용하여 데이터베이스에서 가져올 컬럼(name, phone, age, gender)을 정의
  • 커서는 쿼리 실행 후 결과를 하나씩 가져오기 위해 사용

예시:

EXEC SQL DECLARE cur CURSOR FOR
    SELECT column1, column2 FROM table_name;

 

 

3. EXEC SQL OPEN

  • 용도: 커서를 열어서 SQL 쿼리를 실행하는 구문
  • 설명: OPEN 구문은 선언된 커서를 열어서 실제로 SQL 쿼리를 실행하는 역할
EXEC SQL OPEN cur;
  • *cur**는 앞서 선언한 커서의 이름
  • 커서를 열면 SQL 쿼리가 실행되고, 데이터베이스에서 결과가 반환
  • 커서를 열고 나서야 FETCH 구문을 사용하여 결과를 하나씩 가져옴

 

4. EXEC SQL FETCH

  • 용도: 커서에서 한 행씩 데이터를 가져오는 구문
  • 설명: FETCH 구문은 커서에서 데이터를 한 번에 하나씩 가져오는 역할을 합니다. 커서가 열려 있어야 FETCH가 동작
EXEC SQL FETCH cur INTO :name, :phone, :age, :gender;

 

  • **cur**는 커서의 이름입니다. 이 커서를 통해 SQL 쿼리 결과를 가져옴
  • **:name, :phone, :age, :gender**는 C 변수들입니다. FETCH가 실행되면 커서에서 가져온 데이터를 해당 변수들에 저장
  • 커서가 열린 상태에서 한 행씩 데이터를 가져오게 되며, 이를 반복해서 처리

 


 

 

  • EXEC SQL CONNECT: 데이터베이스에 연결
  • EXEC SQL DECLARE: 커서를 선언
  • EXEC SQL OPEN: 커서를 열어 SQL 쿼리를 실행
  • EXEC SQL FETCH: 커서에서 데이터를 하나씩 가져오기
  • EXEC SQL CLOSE: 커서를 닫고 리소스를 해제
  • EXEC SQL COMMIT/ROLLBACK: 데이터베이스 변경 사항을 저장하거나 취소