
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: 데이터베이스 변경 사항을 저장하거나 취소