[소스] PRO*C의 기본구조와 Indicator의 사용예

Language/Pro*C 2015. 5. 20. 15:37

Pro*c/c++에서 사용되는 기본적인 구조와 Indicator의 사용예를 예제를 통해서 간단히 이해

할 수 있을것으로 본다. 이 예제에서 Indicator는 임무(comm)컬럼의 NULL여부를 판단하기위한
지시자로서 사용되었다. 소스에서는 간단한 주석을 첨부했으므로 이해하는데 그리 어렵지는
않을 것으로 생각된다.
/******************************************************************************
* sample1.pc
*
* 사원번호를 입력받아 사원이 이름, 봉급,임무를 취득
* 임무가 NULL인지를 판단하기위해서 indicator 변수를 사용한다.
******************************************************************************
*
* 선 생성 되어야할 Table 구조
* CREATE TABLE DEPT
* (
* DEPTNO NUMBER(2) NOT NULL,
* DNAME VARCHAR2(14),
* LOC VARCHAR2(13));
*
* CREATE TABLE EMP
* (
* EMPNO NUMBER(4) NOT NULL,
* ENAME VARCHAR2(10),
* JOB VARCHAR2(9),
* MGR NUMBER(4),
* HIREDATE DATE,
* SAL NUMBER(7,2),
* COMM NUMBER(7,2),
* DEPTNO NUMBER(2));
*
*****************************************************************************/
#include <stdio.h>
#include <string.h>
//////////////////////////////////////////////////////////////////////
// VARCHAR 길이 설정
#define UNAME_LEN 20
#define PWD_LEN 40
//////////////////////////////////////////////////////////////////////
// MODE=ORACLE인경우 Declare Section이 필요하지 않다.
// 변수선언
VARCHAR username[UNAME_LEN];
//////////////////////////////////////////////////////////////////////
// varchar가 소문자도 가능하다.
varchar password[PWD_LEN];
//////////////////////////////////////////////////////////////////////
// SELECT문의 결과를 위한 구조체 선언
//////////////////////////////////////////////////////////////////////
struct {
VARCHAR emp_name[UNAME_LEN];
float salary;
float commission;
} emprec;
//////////////////////////////////////////////////////////////////////
// indicator 선언
struct
{
short emp_name_ind;
short sal_ind;
short comm_ind;
} emprec_ind;
//////////////////////////////////////////////////////////////////////
// 입력 호스트 변수 선언
int emp_number;
int total_queried;
//////////////////////////////////////////////////////////////////////
// SQL Communications Area을 포함한다.
// EXEC SQL INCLUDE SQLCA를 사용가능하다.
#include <sqlca.h>
//////////////////////////////////////////////////////////////////////
// 에러처리 함수
void sql_error();
void main()
{
char temp_char[32];
//////////////////////////////////////////////////////////////////////
// 오라클 연결
//////////////////////////////////////////////////////////////////////
// VARCHAR에 사용자이름 복사처리
strncpy((char *) username.arr, "SCOTT", UNAME_LEN);
//////////////////////////////////////////////////////////////////////
// VARCHAR의 길이 설정
username.len = strlen((char *) username.arr);
//////////////////////////////////////////////////////////////////////
// 비밀번호 복사처리
strncpy((char *) password.arr, "TIGER", PWD_LEN);
password.len = strlen((char *) password.arr);
//////////////////////////////////////////////////////////////////////
// 에러핸들러로 sql_error()을 등록
EXEC SQL WHENEVER SQLERROR DO sql_error("ORACLE error--n");
//////////////////////////////////////////////////////////////////////
// 오라클에 연결시 에러가 발생하면 sql_error()을 호출한다.
EXEC SQL CONNECT :username IDENTIFIED BY :password;

printf("nConnected to ORACLE as user: %sn", username.arr);

//////////////////////////////////////////////////////////////////////
// 반복하면서 Employee의 결과를 취득
total_queried = 0;
for (;;)
{
//////////////////////////////////////////////////////////////////////
// 결과가 1403(No data found)이 발생하면 Loop를 멈춘다.
EXEC SQL WHENEVER NOT FOUND DO break;
for (;;)
{
emp_number = 0;
printf("n 사번입력 (0 to quit): ");

//////////////////////////////////////////////////////////////////////
// 사번입력을 얻는다.
gets(temp_char);

emp_number = atoi(temp_char);

if (emp_number == 0)
break;

//////////////////////////////////////////////////////////////////////
// 입력한 사번으로 취득 DATA를 얻는다.
EXEC SQL SELECT ename, sal, NVL(comm, 0)
INTO :emprec INDICATOR :emprec_ind
FROM EMP
WHERE EMPNO = :emp_number;

//////////////////////////////////////////////////////////////////////
// 결과를 출력한다.
printf("nnEmployeetSalaryttCommissionn");
printf("--------t------tt----------n");
//////////////////////////////////////////////////////////////////////
// 출력 String Data의 마지막에 NULL-terminate를 추가한다.
emprec.emp_name.arr[emprec.emp_name.len] = '';
printf("%-8st%6.2ftt", emprec.emp_name.arr, emprec.salary);
if (emprec_ind.comm_ind == -1)
printf("NULLn");
else
printf("%6.2fn", emprec.commission);

total_queried++;
}

if (emp_number == 0) break;
printf("nNot a valid employee number - try again.n");
}

printf("nnTotal rows returned was %d.n", total_queried);

printf("nG'day.nnn");

//////////////////////////////////////////////////////////////////////
// 오라클 연결을 끊는다.
EXEC SQL COMMIT WORK RELEASE;
exit(0);
}
//////////////////////////////////////////////////////////////////////
// 에러처리 함수
//////////////////////////////////////////////////////////////////////
void sql_error(msg)
char *msg;
{
char err_msg[128];
EXEC SQL WHENEVER SQLERROR CONTINUE;
printf("n%sn", msg);

buf_len = sizeof (err_msg);

sqlglm(err_msg, &buf_len, &msg_len);

printf("%.*sn", msg_len, err_msg);

EXEC SQL ROLLBACK RELEASE;

exit(1);
}



출처 - http://younbok.egloos.com/9342733

: