간단한 pro*c 예제

Oracle 2007. 1. 22. 02:21

원본 http://blog.naver.com/julymorning4/100024942934
간단한 pro*c 예제
Sample Tables

Most programming examples in this guide use two sample database tables: DEPT and EMP. Their definitions follow:

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))


Sample Data

Respectively, the DEPT and EMP tables contain the following rows of data:

DEPTNO DNAME LOC
------- ---------- ---------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ------- --------- ------ --------- ------ ------ -------
7369 SMITH CLERK 7902 17-DEC-80 800 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7566 JONES MANAGER 7839 02-APR-81 2975 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
7782 CLARK MANAGER 7839 09-JUN-81 2450 10
7788 SCOTT ANALYST 7566 19-APR-87 3000 20
7839 KING PRESIDENT 17-NOV-81 5000 10
7844 TURNER SALESMAN 7698 08-SEP-81 1500 30
7876 ADAMS CLERK 7788 23-MAY-87 1100 20
7900 JAMES CLERK 7698 03-DEC-81
950 30
7902 FORD ANALYST 7566 03-DEC-81 3000 20
7934 MILLER CLERK 7782 23-JAN-82 1300 10

________________________________________


Sample Program: A Simple Query

One way to get acquainted with Pro*C/C++ and embedded SQL is to study a program example. The program listed below is also available on-line in the file sample1.pc in your Pro*C/C++ demo directory.

The program connects to Oracle, then loops, prompting the user for an employee number. It queries the database for the employee's name, salary, and commission, displays the information, and then continues the loop. The information is returned to a host structure. There is also a parallel indicator structure to signal whether any of the output values SELECTed might be null.

You should precompile sample programs using the precompiler option MODE=ORACLE.

/*
* sample1.pc
*
* Prompts the user for an employee number,
* then queries the emp table for the employee's
* name, salary and commission. Uses indicator
* variables (in an indicator struct) to determine
* if the commission is NULL.
*
*/

#include <stdio.h>
#include <string.h>


/* Define constants for VARCHAR lengths. */
#define UNAME_LEN 20
#define PWD_LEN 40

/* Declare variables. No declare section is
needed if MODE=ORACLE. */
VARCHAR username[UNAME_LEN]; /* VARCHAR is an Oracle-supplied struct */
varchar password[PWD_LEN]; /* varchar can be in lower case also. */
/* Define a host structure for the output values of
a SELECT statement. */
struct
{
VARCHAR emp_name[UNAME_LEN];
float salary;
float commission;
} emprec;

/* Define an indicator struct to correspond
to the host output struct. */
struct
{
short emp_name_ind;
short sal_ind;
short comm_ind;
} emprec_ind;

/* Input host variable. */
int emp_number;

int total_queried;

/* Include the SQL Communications Area.
You can use #include or EXEC SQL INCLUDE. */
#include <sqlca.h>


/* Declare error handling function. */
void sql_error();


main()
{
char temp_char[32];

/* Connect to ORACLE--
* Copy the username into the VARCHAR.
*/
strncpy((char *) username.arr, "SCOTT", UNAME_LEN);

/* Set the length component of the VARCHAR. */
username.len = strlen((char *) username.arr);

/* Copy the password. */
strncpy((char *) password.arr, "TIGER", PWD_LEN);
password.len = strlen((char *) password.arr);
/* Register sql_error() as the error handler. */
EXEC SQL WHENEVER SQLERROR DO sql_error("ORACLE error--\n");

/* Connect to ORACLE. Program will call sql_error()
* if an error occurs when connecting to the default database.
*/
EXEC SQL CONNECT :username IDENTIFIED BY :password;

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

/* Loop, selecting individual employee's results */

total_queried = 0;

for (;;)
{
/* Break out of the inner loop when a
* 1403 ("No data found") condition occurs.
*/
EXEC SQL WHENEVER NOT FOUND DO break;
for (;;)
{
emp_number = 0;
printf("\nEnter employee number (0 to quit): ");
gets(temp_char);
emp_number = atoi(temp_char);
if (emp_number == 0)
break;

EXEC SQL SELECT ename, sal, comm
INTO :emprec INDICATOR :emprec_ind
FROM EMP
WHERE EMPNO = :emp_number;

/* Print data. */

printf("\n\nEmployee\tSalary\t\tCommission\n");
printf("--------\t------\t\t----------\n");
/* Null-terminate the output string data. */
emprec.emp_name.arr[emprec.emp_name.len] = '\0';
printf("%-8s\t%6.2f\t\t",
emprec.emp_name.arr, emprec.salary);

if (emprec_ind.comm_ind == -1)
printf("NULL\n");
else
printf("%6.2f\n", emprec.commission);

total_queried++;
} /* end inner for (;;) */
if (emp_number == 0) break;
printf("\nNot a valid employee number - try again.\n");
} /* end outer for(;;) */

printf("\n\nTotal rows returned was %d.\n", total_queried);
printf("\nG'day.\n\n\n");

/* Disconnect from ORACLE. */
EXEC SQL COMMIT WORK RELEASE;
exit(0);
}


void
sql_error(msg)
char *msg;
{
char err_msg[128];
int buf_len, msg_len;

EXEC SQL WHENEVER SQLERROR CONTINUE;

printf("\n%s\n", msg);
buf_len = sizeof (err_msg);
sqlglm(err_msg, &buf_len, &msg_len);
printf("%.*s\n", msg_len, err_msg);

EXEC SQL ROLLBACK RELEASE;
exit(1);
}
, .


원본 http://blog.naver.com/julymorning4/100024942961

[예제]텍스트 파일을 읽어 DB에...
/*======================================================*/
/* 프로그램 그룹 : 기준 정보*/
/* 프로그램명:*/
/* 설명: 날씨 정보 텍스트 파일을 읽어 없으면*/
/* Insert있으면 Update*/
/**/
/* 작성일시: 2005.04.XX */
/* 작성자:*/
/* INPUT DATA: 날씨 정보 파일(텍스트) */
/* REF. DATA : None.*/
/* OUTPUT DATA : WEATHER*/
/*======================================================*/
/* 변경 History */
/*======================================================*/
/* 2005.04.07 DEV START */
/**/
/*======================================================*/

#include "../../comm/jclee.h"
#define READ_SIZE83

EXEC SQL include sqlca.h;

/*======================================================*/
/* Global 변수 선언 */
/*======================================================*/
FILE* fi;
chardummy[100];
charInput_Data [READ_SIZE];
charInput_Buf[READ_SIZE];
longgl_job = 0;/* Job Status*/


/*======================================================*/
/* 프로그램 정보(ID, Name)*/
/*======================================================*/
char Pg_Info [2][50];


/*======================================================*/
/* 프로그램 공통 함수 */
/*======================================================*/
void Check_Command(int argc, char *argv[]);
void DataLogging();
intData_Processing();
intFile_Open();
void File_Close();
void Save_DataFile();


/*======================================================*/
/* READ DATA STRUCTURE*/
/*======================================================*/
typedef struct Read_Record {
char Wth_Date [ 8];/* 날씨정보 기준일 */
char Code [ 3];/* 코드*/
char Am_Wth_Code[ 2];/* 오전 날씨 아이콘*/
char Pm_Wth_Code[ 2];/* 오후 날씨 아이콘*/
char Min_Temp [ 3];/* 당일 최저 기온*/
char Max_Temp [ 3];/* 당일 최고 기온*/
char Am_Rain_Rate [ 3];/* 오전 강수 확률*/
char Pm_Rain_Rate [ 3];/* 오후 강수 확률*/
char Min_Humi [ 3];/* 당일 최저 습도*/
char Max_Humi [ 3];/* 당일 최고 습도*/
char Wth_Info [50];/* 날씨 요약 정보*/
} Read_Rec;


/*======================================================*/

/*======================================================*/
/* REAL STRUCTURE */
/*======================================================*/
typedef struct Real_Record {
char Wth_Date[ 8+1];/* 날씨정보 기준일 */
char Code[ 3+1];/* 점코드*/
char Am_Wth_Code [ 2+1];/* 오전 날씨 아이콘*/
char Pm_Wth_Code [ 2+1];/* 오후 날씨 아이콘*/
char Min_Temp[ 3+1];/* 당일 최저 기온*/
char Max_Temp[ 3+1];/* 당일 최고 기온*/
char Am_Rain_Rate[ 3+1];/* 오전 강수 확률*/
char Pm_Rain_Rate[ 3+1];/* 오후 강수 확률*/
char Min_Humi[ 3+1];/* 당일 최저 습도*/
char Max_Humi[ 3+1];/* 당일 최고 습도*/
char Wth_Info[50+1];/* 날씨 요약 정보*/
} Real_Rec;

Read_RecReadRecord;
Real_RecRealRecord ;

/*=======================================================*/
/* */
/* MAIN START......*/
/* */
/*=======================================================*/
void main(int argc, char *argv[])
{
int ret_val;

/* argument check & variable init */
Check_Command(argc, &argv[0]);

DB_Connect(Pg_Info[0]);

ret_val = File_Open();

if ( ret_val != 0 ) {
printf("FILE OPEN Error! \n");
return;
}

/* FILE을 읽어 날씨 정보 테이블(WEATHER)에 저장 */
gl_job = Data_Processing();

if (gl_job != 0) {
DB_RollbackR();
}
else {
Save_DataFile();
DB_CommitR();
}

/* File_Close(); */
File_Close();

Pgm_End(Pg_Info[0], 0);
}

/*=======================================================*/
/* 함수명 : Check_Command*/
/* 기능 : Command Syntax 확인*/
/*=======================================================*/
void Check_Command(int argc, char *argv[]) {

/* MEM(Pg_Info); */
memset(Pg_Info, 0, sizeof(Pg_Info));

strcpy(Pg_Info[0], argv[0]);
strcpy(Pg_Info[1], "날씨 정보 다운로드");

/* argument print */
Log_Arg(argc, &argv[0], Pg_Info[0]);

/* Program Start Log.... */
Log_Line(Pg_Info[0], "====================Loggging Start===================");
Pgm_Start(Pg_Info[0]);
}



/*=====================================================*/
/* 함수명 : Data_Processing*/
/* 기능 : SAM FILE을 날씨 정보 테이블(WEATHER)에 저장*/
/*=====================================================*/
intData_Processing()
{
int pos = 0, col = 0;
int cnt = 0;
int Tot_Cnt = 0;
int Read_Chk = 0;
charCur_Date[9];
int Chk_Cnt;
charLog_Text[1024];


Read_Chk = fread (Input_Data,sizeof(Input_Data) ,1, fi) ;

while ( Read_Chk > 0 )
{

memset(Cur_Date, 0x00, sizeof(Cur_Date));
memset(&ReadRecord, 0x00,sizeof(ReadRecord));
memset(&RealRecord, 0x00, sizeof(RealRecord));

col = 0;

strncpy(ReadRecord.Wth_Date, Input_Data+col, 8); col+=8;
strncpy(ReadRecord.Code, Input_Data+col, 3); col+=3;
strncpy(ReadRecord.Am_Wth_Code,Input_Data+col, 3); col+=2;
strncpy(ReadRecord.Pm_Wth_Code,Input_Data+col, 3); col+=2;
strncpy(ReadRecord.Min_Temp, Input_Data+col, 3); col+=3;
strncpy(ReadRecord.Max_Temp, Input_Data+col, 3); col+=3;
strncpy(ReadRecord.Am_Rain_Rate, Input_Data+col, 3); col+=3;
strncpy(ReadRecord.Pm_Rain_Rate, Input_Data+col, 3); col+=3;
strncpy(ReadRecord.Min_Humi, Input_Data+col, 3); col+=3;
strncpy(ReadRecord.Max_Humi, Input_Data+col, 3); col+=3;
strncpy(ReadRecord.Wth_Info, Input_Data+col, 50);

cnt = cnt + 1 ;

strncpy(RealRecord.Wth_Date,ReadRecord.Wth_Date,sizeof(ReadRecord.Wth_Date));
strncpy(RealRecord.Code ,ReadRecord.Code ,sizeof(ReadRecord.Code ));
strncpy(RealRecord.Am_Wth_Code,ReadRecord.Am_Wth_Code,sizeof(ReadRecord.Am_Wth_Code));
strncpy(RealRecord.Pm_Wth_Code,ReadRecord.Pm_Wth_Code,sizeof(ReadRecord.Pm_Wth_Code));
strncpy(RealRecord.Min_Temp ,ReadRecord.Min_Temp ,sizeof(ReadRecord.Min_Temp ));
strncpy(RealRecord.Max_Temp ,ReadRecord.Max_Temp ,sizeof(ReadRecord.Max_Temp ));
strncpy(RealRecord.Am_Rain_Rate ,ReadRecord.Am_Rain_Rate ,sizeof(ReadRecord.Am_Rain_Rate ));
strncpy(RealRecord.Pm_Rain_Rate ,ReadRecord.Pm_Rain_Rate ,sizeof(ReadRecord.Pm_Rain_Rate ));
strncpy(RealRecord.Min_Humi ,ReadRecord.Min_Humi ,sizeof(ReadRecord.Min_Humi ));
strncpy(RealRecord.Max_Humi ,ReadRecord.Max_Humi ,sizeof(ReadRecord.Max_Humi ));
strncpy(RealRecord.Wth_Info ,ReadRecord.Wth_Info ,sizeof(ReadRecord.Wth_Info ));

printf("Read Data Stream => [%s] \n",Input_Data);

printf("Read Data Check1 => [%s][%s][%s][%s][%s][%s][%s][%s][%s][%s]\n",
RealRecord.Wth_Date,RealRecord.Code,
RealRecord.Am_Wth_Code, RealRecord.Pm_Wth_Code,
RealRecord.Am_Rain_Rate, RealRecord.Pm_Rain_Rate,
RealRecord.Max_Temp,RealRecord.Min_Temp,
RealRecord.Max_Humi,RealRecord.Min_Humi
);
printf("Read Data Check2 => [%s] \n\n",RealRecord.Wth_Info);

/*-------------------------------------------------------------*/
EXEC SQL
SELECT COUNT(WTH_DATE)
INTO :Chk_Cnt
FROM WEATHER
WHEREWTH_DATE = :RealRecord.Wth_Date
ANDCode = SUBSTR(:RealRecord.Code,2,2);

/* ------------------------------------------------------------*/
/* 기존 데이터가 없는 경우 */
/* ------------------------------------------------------------*/
if (Chk_Cnt == 0) {
/* 단기 3일치엔 습도가 제공 되지만 주간예보 5일치엔 습도가 제공안됨 */
if (strcmp(RealRecord.Max_Humi, " ") == 0) {
EXEC SQL
INSERT INTO WEATHER (
Code, /* SAM FILE에서 넘어오는 점코드 */
WTH_DATE, /* 일자 */
AM_WTH_CODE,/* 오전 날씨*/
PM_WTH_CODE,/* 오후 날씨*/
AM_RAIN_RATE, /* 오전 비(or SNOW)올 확률*/
PM_RAIN_RATE, /* 오후 비(or SNOW)올 확률*/
MIN_TEMP, /* 최저 기온*/
MAX_TEMP, /* 최고 기온*/
WTH_INFO/* 개황 */
)
VALUES (
SUBSTR(:RealRecord.Code,2,2),
:RealRecord.Wth_Date,
:RealRecord.Am_Wth_Code,
:RealRecord.Pm_Wth_Code,
TO_NUMBER(:RealRecord.Am_Rain_Rate),
TO_NUMBER(:RealRecord.Pm_Rain_Rate),
TO_NUMBER(:RealRecord.Min_Temp),
TO_NUMBER(:RealRecord.Max_Temp),
:RealRecord.Wth_Info
);

}
else {
EXEC SQL
INSERT INTO WEATHER (
Code, /* SAM FILE에서 넘어오는 점코드 */
WTH_DATE, /* 일자 */
AM_WTH_CODE,/* 오전 날씨*/
PM_WTH_CODE,/* 오후 날씨*/
AM_RAIN_RATE, /* 오전 비(or SNOW)올 확률*/
PM_RAIN_RATE, /* 오후 비(or SNOW)올 확률*/
MIN_TEMP, /* 최저 기온*/
MAX_TEMP, /* 최고 기온*/
MIN_HUMI, /* 최저 습도*/
MAX_HUMI, /* 최고 습도*/
WTH_INFO/* 개황 */
)
VALUES (
SUBSTR(:RealRecord.Code,2,2),
:RealRecord.Wth_Date,
:RealRecord.Am_Wth_Code,
:RealRecord.Pm_Wth_Code,
TO_NUMBER(:RealRecord.Am_Rain_Rate),
TO_NUMBER(:RealRecord.Pm_Rain_Rate),
TO_NUMBER(:RealRecord.Min_Temp),
TO_NUMBER(:RealRecord.Max_Temp),
TO_NUMBER(:RealRecord.Min_Humi),
TO_NUMBER(:RealRecord.Max_Humi),
:RealRecord.Wth_Info
);
}

if (SQLCODE != SQL_OK) {
DB_Error(&Pg_Info[0]);
printf("\n####### 날씨 Insert Error Data(WEATHER) #######\n");
printf("\n[%d]\n[%s]\n",SQLCODE,SQLERRTXT);
Log_Line(Pg_Info[0],"####### 날씨 Insert Error Data(WEATHER) #######\n");
DataLogging();
return -1;
}
else {
printf("####### Insert OK #######\n\n");
}
}
/*-----------------------------------------------*/
/* 기존 데이터가 있는 경우 */
/*-----------------------------------------------*/
else {
/* 단기 3일치엔 습도가 제공 되지만 주간예보 5일치엔 습도가 제공안됨 */
if (strcmp(RealRecord.Max_Humi, " ") == 0) {
EXEC SQL
UPDATE WEATHER
SETAM_WTH_CODE= :RealRecord.Am_Wth_Code,
PM_WTH_CODE= :RealRecord.Pm_Wth_Code,
AM_RAIN_RATE = TO_NUMBER(:RealRecord.Am_Rain_Rate),
PM_RAIN_RATE = TO_NUMBER(:RealRecord.Pm_Rain_Rate),
MIN_TEMP = TO_NUMBER(:RealRecord.Min_Temp),
MAX_TEMP = TO_NUMBER(:RealRecord.Max_Temp),
WTH_INFO = RTRIM(:RealRecord.Wth_Info)
WHEREWTH_DATE = :RealRecord.Wth_Date
ANDCode = SUBSTR(:RealRecord.Code, 2,2);

}
else {
EXEC SQL
UPDATE WEATHER
SETAM_WTH_CODE= :RealRecord.Am_Wth_Code,
PM_WTH_CODE= :RealRecord.Pm_Wth_Code,
AM_RAIN_RATE = TO_NUMBER(:RealRecord.Am_Rain_Rate),
PM_RAIN_RATE = TO_NUMBER(:RealRecord.Pm_Rain_Rate),
MIN_TEMP = TO_NUMBER(:RealRecord.Min_Temp),
MAX_TEMP = TO_NUMBER(:RealRecord.Max_Temp),
MIN_HUMI = TO_NUMBER(:RealRecord.Min_Humi),
MAX_HUMI = TO_NUMBER(:RealRecord.Max_Humi),
WTH_INFO = RTRIM(:RealRecord.Wth_Info)
WHEREWTH_DATE = :RealRecord.Wth_Date
ANDCode = SUBSTR(:RealRecord.Code, 2, 2);
}

if (SQLCODE != SQL_OK) {
DB_Error(&Pg_Info[0]);
printf("\n[%d]\n[%s]\n",SQLCODE,SQLERRTXT);
Log_Line(Pg_Info[0],"####### 날씨 Update Error Data(TTNMMM) #######\n");
DataLogging();
return -1;
}
else {
printf("####### Update OK #######");
}
}

Tot_Cnt = Tot_Cnt + 1;

memset(Input_Data,0x00,sizeof(Input_Data));
memset(Input_Buf ,0x00,sizeof(Input_Buf ));
Read_Chk = fread(Input_Buf ,sizeof(Input_Data) + 1,1,fi);

strncpy(Input_Data, Input_Buf+1, sizeof(Input_Data));

}

printf("---------------------------------------\n");
printf("총 Data 건수 : [%d]\n", Tot_Cnt);

MEM(Log_Text);
sprintf(Log_Text, "\n총 Data 건수 : [%d]\n", Tot_Cnt);

return 0;
}


/*=================================================*/
/* 함수명 : File_Open()*/
/* 기능 : 날씨 정보 SAM File Open*/
/*=================================================*/
int File_Open()
{
char *open_in_file = "./nalssi.dat";

fi = fopen(open_in_file, "rb");
if (!fi) {
printf("\ 날씨 파일이 없습니다.... \n", stderr);
return 1;
}
return 0;
}


/*===========================================================*/
/* 함수명 : Save_DataFile()*/
/* 기능 : 사용한 파일은 별도의 디렉토리에 이름을 바꿔 보관 */
/*===========================================================*/
void Save_DataFile() {
charbuff[250];
charNow [14+1];

memset(Now,0x00,sizeof(Now));
memset(buff, 0x00, sizeof(buff));

EXEC SQL
SELECT TO_CHAR(SYSDATE, 'yyyymmddhh24miss')
INTO :Now
FROM DUAL;

sprintf(buff, "mv ./nalssi.dat ./data/nalssi.dat_%s", Now);

printf("Command in => [%s] \n",buff);

system(buff);
}


/*======================================================*/
/* 함수명 : File_Close()*/
/* 기능 : 날씨 정보 SAM File Closing*/
/*======================================================*/
void File_Close()
{
fclose(fi);
}

/*======================================================*/
/* 함수명 : DataLogging() */
/* 기능 : Insert 오류가 발생한 데이터를 로깅*/
/*======================================================*/
void DataLogging() {

char Log_Text[1024];
MEM(Log_Text);

printf("Read Data Stream => [%s] \n",Input_Data);
printf("Read Data Check1 => [%s][%s][%s][%s][%s][%s][%s][%s][%s][%s]\n",
RealRecord.Wth_Date,RealRecord.Code,
RealRecord.Am_Wth_Code, RealRecord.Pm_Wth_Code,
RealRecord.Am_Rain_Rate, RealRecord.Pm_Rain_Rate,
RealRecord.Max_Temp,RealRecord.Min_Temp,
RealRecord.Max_Humi,RealRecord.Min_Humi
);
printf("Read Data Check2 => [%s] \n\n",RealRecord.Wth_Info);

sprintf(Log_Text, "Insert/Update Error Data :::: [%s][%s][%s][%s][%s][%s][%s][%s][%s][%s]\n",
RealRecord.Wth_Date,RealRecord.Code,
RealRecord.Am_Wth_Code, RealRecord.Pm_Wth_Code,
RealRecord.Am_Rain_Rate, RealRecord.Pm_Rain_Rate,
RealRecord.Max_Temp,RealRecord.Min_Temp,
RealRecord.Max_Humi,RealRecord.Min_Humi
);

Log_Line(Pg_Info[0],Log_Text);
Log_Line(Pg_Info[0],"####################################\n");
}

, .

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

void sqlerror();

EXEC SQL BEGIN DECLARE SECTION;
char *connstr = "scott/tiger";
char db_ename[30];
intdb_deptno;
EXEC SQL END DECLARE SECTION;

void main() {
EXEC SQL WHENEVER SQLERROR DO sqlerror();
EXEC SQL WHENEVER SQLWARNING CONTINUE;
EXEC SQL CONNECT :connstr;

EXEC SQL DECLARE emp_cursor CURSOR FOR
SELECT ENAME, DEPTNO
FROM EMP;

EXEC SQL OPEN emp_cursor;

EXEC SQL WHENEVER NOT FOUND DO break;
for (;;) {
EXEC SQL FETCH emp_cursor INTO :db_ename, :db_deptno;
printf("\t%s\t%i\n", db_ename, db_deptno);
}

EXEC SQL CLOSE emp_cursor;
EXEC SQL COMMIT WORK RELEASE;
return;
}

void sqlerror() {
printf("Stop Error:\t%25i\n", sqlca.sqlcode);
EXEC SQL WHENEVER SQLERROR CONTINUE;
EXEC SQL ROLLBACK WORK RELEASE;
return;
}

원본 http://blog.naver.com/julymorning4/100024943004

, .

원본 http://blog.naver.com/st95041/40001613322

예전에 comp76에서 작업한 예입니다. test.pc 에 있는 부분중 일부는 comp66의 현 상황에 맞게 고쳐져 있습니다. 참고하시길..


[dbhw00@comp76]/home/dbhw00/public_html/cgi-bin 52 > ls

proc.mk test.pc


[dbhw00@comp76]/home/dbhw00/public_html/cgi-bin 53 > proc test.pc


/* pc화일을 pre-compile한다. */

Pro*C/C++: Release 2.1.3.0.0 - Production on Mon Nov 24 21:15:18 1997

Copyright (c) Oracle Corporation 1979, 1994. All rights reserved.

System default option values taken from: /home/oracle/oracle7/proc/pmscfg.h

/* pre-compile 하면 c 화일이 생성된다 */


[dbhw00@comp76]/home/dbhw00/public_html/cgi-bin 54 > ls -al

total 5232

drwxr-xr-x 2 dbhw00 50000 512 Nov 24 21:15 ./

drwxr-xr-x 3 dbhw00 50000 512 Nov 24 21:06 ../

-rw--xr-x 1 dbhw00 50000 8115 Nov 24 18:41 proc.mk

-rw------- 1 dbhw00 50000 17835 Nov 24 21:15 test.c

-rw--xr-x 1 dbhw00 50000 3271 Nov 24 20:22 test.pc


/* 다음과 같이 make 하면 실행화일이 생성된다 */


[dbhw00@comp76]/home/dbhw00/public_html/cgi-bin 55 > make -f proc.mk EXE=test.cg

i OBJS=test.o

cc -I. -O -xcg92 -I/home/oracle/oracle7/sqllib/public -c test.c

ld -dy /home/oracle/oracle7/lib/crti.o /home/oracle/oracle7/lib/crt1.o /home/ora

cle/oracle7/lib/__fstd.o -R /opt/SUNWcluster/lib -Y P,/lib:/usr/lib:/usr/dt/lib:

/usr/openwin/lib:/usr/ucblib:/opt/SUNWcluster/lib:/usr/ccs/lib:/usr/lib -Qy -lc

/home/oracle/oracle7/lib/crtn.o -L/home/oracle/oracle7/lib -o test.cgi test.o -l

sql /home/oracle/oracle7/lib/osntab.o -lsqlnet -lora -lsqlnet -lpls -lora -lnlsr

tl3 -lc3v6 -lcore3 -lnlsrtl3 -lcore3 -lsocket -lnsl -lm -ldl -laio -lsocket -lns

l -lm -ldl -laio


[dbhw00@comp76]/home/dbhw00/public_html/cgi-bin 57 > ls -al

total 10416

drwxr-xr-x 2 dbhw00 50000 512 Nov 24 21:16 ./

drwxr-xr-x 3 dbhw00 50000 512 Nov 24 21:06 ../

-rw-r--r-- 1 dbhw00 50000 8115 Nov 24 18:41 proc.mk

-rw------- 1 dbhw00 50000 17835 Nov 24 21:15 test.c

-rwx------ 1 dbhw00 50000 2633868 Nov 24 21:16 test.cgi*

-rw------- 1 dbhw00 50000 7944 Nov 24 21:16 test.o

-rw-r--r-- 1 dbhw00 50000 3271 Nov 24 20:22 test.pc

------------------------------------------------------------------

test.pc 의 내용


#include <stdio.h>

#include <stdlib.h>

#include <ctype.h>

#include <sys/types.h>

#include <time.h>


/* 각자의 id와 passwd로 수정 */

#define USERID "dbhw000"

#define PASSWD "dbhw000"


#define ORACLE_HOME_ENV "ORACLE_HOME=/usr/local/oracle"

#define ORACLE_SID_ENV "ORACLE_SID=ORA8"


void Print_html();

int DB_Task();

void error_out(char *msg1);


EXEC SQL INCLUDE sqlca;

EXEC SQL INCLUDE oraca;

EXEC ORACLE OPTION (ORACA=YES);

EXEC SQL BEGIN DECLARE SECTION;


int id;

VARCHAR name[20];

VARCHAR address[200];

VARCHAR phone[14];

VARCHAR email[100];

VARCHAR dbuid[20];

VARCHAR dbpwd[20];

VARCHAR servicename[20];

EXEC SQL END DECLARE SECTION;


main(){


/* 환경 변수 설정 부분 */

putenv(ORACLE_HOME_ENV);

putenv(ORACLE_SID_ENV);


/* html 문서임을 표시, \n이 2개 이상 */

printf("Content-type: text/html\n\n");


DB_Task();

Print_html();

exit(0);

}

/* DB 작업과 sqlca를 이용한 에러 처리 */

int DB_Task() {


int idnum;


/* ID, Passwd 설정 */

/* VARCHAR 타입은 문자열을 위한 arr과 문자열 길이를 위한 len으로 구성 */

strcpy(dbuid.arr, USERID); dbuid.len = strlen(USERID);

strcpy(dbpwd.arr, PASSWD); dbpwd.len = strlen(PASSWD);


/* DB 연결 */

EXEC SQL CONNECT :dbuid IDENTIFIED BY :dbpwd;


/* test 테이블로부터 id, ..., email을 검색하여 :id, ..., :email 에 대입 */

idnum = 1;

EXEC SQL SELECT id, name, address, email

INTO :id, :name, :address, :email

FROM test

WHERE id=:idnum;


if(sqlca.sqlcode!=0) {

EXEC SQL WHENEVER SQLERROR CONTINUE;

EXEC SQL ROLLBACK WORK RELEASE;


error_out("SQL문에 오류가 있습니다.");

return 1;

}


EXEC SQL WHENEVER SQLERROR CONTINUE;

EXEC SQL COMMIT WORK RELEASE;


return 0;

}


/* DB 작업과 레이블을 이용한 에러 처리 */

int DB_Task(){


int idnum;


strcpy(dbuid.arr, USERID); dbuid.len = strlen(USERID);

strcpy(dbpwd.arr, PASSWD); dbpwd.len = strlen(PASSWD);


/* DB 작업중 에러 발생하면 ErrExit로 감 */

EXEC SQL WHENEVER SQLERROR GOTO ErrExit;

EXEC SQL CONNECT :dbuid IDENTIFIED BY :dbpwd;


idnum = 1;


EXEC SQL SELECT id, name, address, email

INTO :id, :name, :address, :email

FROM test

WHERE id=:idnum;

EXEC SQL WHENEVER SQLERROR CONTINUE;

EXEC SQL COMMIT WORK RELEASE;


return 0;


ErrExit:


EXEC SQL WHENEVER SQLERROR CONTINUE;

EXEC SQL ROLLBACK WORK RELEASE;

error_out("시스템에 문제가 발생했습니다");

return 1;


}


void Print_html() {

printf("<html>\n");

printf("<head>\n");

printf("<title> Query 1 </title>\n");

printf("</head>\n");

printf("<body bgcolor=#ffffff >\n");

printf("<H1> <Center> <U> QUERY 1 </U> </Center> </H1>\n");

printf("<center>\n");

printf("<Table Border=1>\n");

printf("<Tr>\n");

printf("<Td> <Center> 구분 </Center> </td>\n");

printf("<Td > <center>내 용</center></td>\n");

printf("</tr>\n");

printf("<Tr>\n");

printf("<Td> <Center> ID </Center> </td>\n");

printf("<Td > %d</td>\n", id);

printf("</tr>\n");

printf("<Tr>\n");

printf("<Td> <Center> 이름 </Center> </td>\n");

printf("<Td > %s</td>\n", name.arr);

printf("</tr>\n");

printf("<Tr>\n");

printf("<Td> <Center> 주소 </Center> </td>\n");

printf("<Td > %s</td>\n", address.arr);

printf("</tr>\n");

printf("<Tr>\n");

printf("<Td> <Center> E-mail </Center> </td>\n");

printf("<Td > %s</td>\n", email.arr);

printf("</tr>\n");

printf("</Table>\n");

printf("</center>\n");

printf("<Hr Width=100%%>\n");

printf("<Center>\n");

printf("</body>\n");

}


comp66>/usr/loca/oracle/precomp/demo/proc 내에 있는 .pc 파일들을 참고할 것.


< 참고 문헌 >


Rick F. van der Lans, "Introduction to SQL", Addison-Wesley

Rick F. van der Lans, "The SQL Guide to ORACLE", Addison-Wesley

Jim Melton, "Understanding the new SQL", Morgan Kaufmann.

원래소스 http://dbmain.snu.ac.kr/courses/DB99/proc.html

, .