Pro*C에서 pl/sql 호출하여 커서로 결과 출력하기.
여기서는 plsql block을 사용합니다.
다시 말해서 Pro*C에서 plsql을 사용한다는 의미입니다.
그래서 빌드를 할 때 계정 정보도 입력을 해야 합니다.
proc SQLCHECK=SEMANTICS iname=employees.pc userid=hr/password@ORCLPDB1
그리고 gcc 컴파일에서도 include 경로가 추가가 됩니다.
gcc -o employees employees.c -L$ORACLE_HOME/lib -I$ORACLE_HOME/precomp/public -I/opt/oracle/product/19c/dbhome_1/rdbms/public -lclntsh -lpthread -ldl -lm
#include <stdio.h>
#include <string.h>
#include <sqlca.h>
/* SQLCA는 SQL Communications Area로, SQL 작업의 결과를 저장합니다. */
/* 데이터베이스 연결에 필요한 변수들 */
EXEC SQL BEGIN DECLARE SECTION;
char username[20] = "hr";
char password[20] = "password";
VARCHAR connect_string[200];
int department_id = 60; /* 조회할 부서 ID */
int employee_id;
char first_name[20];
char last_name[20];
char email[50];
char hire_date[20];
char job_id[10];
EXEC SQL END DECLARE SECTION;
void fetch_employee_info();
int main() {
strcpy(connect_string.arr, "//localhost:1521/ORCLPDB1");
connect_string.len = strlen(connect_string.arr);
/* 데이터베이스 연결 */
EXEC SQL CONNECT :username IDENTIFIED BY :password USING : connect_string;
if (sqlca.sqlcode != 0) {
printf("데이터베이스 연결 실패: %s\n", sqlca.sqlerrm.sqlerrmc);
return 1;
}
/* 직원 정보 조회 */
fetch_employee_info();
/* 데이터베이스 연결 해제 */
EXEC SQL COMMIT WORK RELEASE;
return 0;
}
void fetch_employee_info() {
EXEC SQL BEGIN DECLARE SECTION;
SQL_CURSOR employee_cursor;
EXEC SQL END DECLARE SECTION;
// /* 커서 열기 */
EXEC SQL ALLOCATE :employee_cursor;
// /* 프로시저 호출 */
EXEC SQL EXECUTE
BEGIN
hr_pkg.get_employee_info(:department_id, :employee_cursor);
END;
END-EXEC;
if (sqlca.sqlcode != 0) {
printf("프로시저 호출 실패: %s\n", sqlca.sqlerrm.sqlerrmc);
EXEC SQL ROLLBACK WORK;
return;
}
// /* 커서에서 데이터 가져오기 */
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1) {
EXEC SQL FETCH :employee_cursor INTO :employee_id, :first_name, :last_name, :email, :hire_date, :job_id;
if (sqlca.sqlcode == 1403) {
break;
} else if (sqlca.sqlcode != 0) {
printf("데이터 가져오기 실패: %s\n", sqlca.sqlerrm.sqlerrmc);
break;
}
/* 직원 정보 출력 */
printf("직원 ID: %d, 이름: %s %s, 이메일: %s, 입사일: %s, 직책: %s\n",
employee_id, first_name, last_name, email, hire_date, job_id);
}
// /* 커서 닫기 */
EXEC SQL CLOSE :employee_cursor;
}