proc로 cgi만들기(1) - 김태양[오라클개발자교육/오라클/ORACLE강좌...

proc로 cgi만들기(1) - 김태양[오라클개발자교육/오라클/ORACLE강좌...

제가 몇년전에 올린 글이었는데 거의 필요 없겠지만서도 혹시 필요한 분 계실까봐 이렇게 다시 한번 올립니다.

예제1

Web에서 Oracle DB에 접근하는 CGI(Common Gateway Interface)를

Oracle 에서 제공하는 Pro C로 만들어 봅시다.

Pro C는 C언어를 기본으로 하고 있으니 C만 아시면 쉽게 이해하실 수 있구요

cgi를 작성하기 위하여 cgic library를 이용합니다.

cgic library에 대한 구체적인 함수나 환경변수들에 대한 설명은 http://www.boutell.com/cgic 에 있습니다.

오늘은 Oracle DB 에 접속하기 위한 기본적인 설정 및 접속 방법에 대하여 알아보도록 하겠습니다.

다음 코드를 살펴보면...

#include

#include "/home/superman/cgic/cgic.h"

#define USERNAME "superman" // Username 을 저장

#define PASSWORD "superman" // Password 를 저장

#define DBSTRING "DB" // DBString을 저장

EXEC SQL BEGIN DECLARE SECTION; // SQL문에 연관되어 사용되어질 변수들에 대한 선언을 시작한다는 문구

char *username = USERNAME;

char *password = PASSWORD;

char *dbstring = DBSTRING;

...

...

EXEC SQL END DECLARE SECTION; // 선언종료

EXEC SQL INCLUDE sqlca;

void sqlerror(); // oracle DB error났을때 error처리 함수

int getCgiParameter(); // html파일에서 사용자가 입력했던 데이터를 받아들이는 함수

void setMemory ( void ); // 변수들을 초기화해주기 위한 함수

int cgiMain ( void ) // 시작

{

int result;

// 여기서 부터 4줄은 web에서 사용자들이 nobody로 접속하게 되므로 oracle 환경 설정이 필요하기 때문에 적어주는 것이다. //

putenv("ORACLE_HOME=/usr/oracle/733"); // oracle 홈 디렉토리 설정

putenv("ORACLE_SID=DB"); // SID 설정

putenv("NLS_LANG=American_America.ko16ksc5601"); // 언어 설정 ( 한국어 )

putenv("LD_LIBRARY_PATH=/usr/oracle/733/lib"); // oracle library 디렉토리 설정

// 여기까지 //

EXEC SQL WHENEVER SQLERROR DO sqlerror(); // oracle db error가 났을경우 sqlerror()함수를 실행시키라는 명령

EXEC ORACLE OPTION(HOLD_CURSOR=NO); // cursor를 무한정 잡을경우 no로 설정. 그렇지 않다면 yes로 설정

EXEC SQL CONNECT :username IDENTIFIED BY :password USING :dbstring; // oracle db에 접속

...

...

}

ps) 위의 문구중 Bold체로 되어 있는 것은 반드시 C code에 들어있어야만 하는 것들입니다.

위와 같은 코딩을 작성하면 기본적인 환경설정 및 접속이 완료됩니다. 그 다음부터 본인이 원하는 query등을 날려서 결과를 받은 후 web에 뿌려주면 됩니다.

아래에서 예제를 가지고 pro C를 이용하여 exam.cgi를 작성하여 보도록 히겠습니다.

[예제] - html로 입력받은 여러가지 입력자료들을 DB에 insert하는 cgi

:

#include "stdio.h"

#include "/home/superman/cgic/cgic.h"

#define USERNAME "superman"

#define PASSWORD "superman"

#define DBSTRING "DB"

EXEC SQL BEGIN DECLARE SECTION;

// DB에 관련된 변수들을 선언

char *username = USERNAME;

char *password = PASSWORD;

char *dbstring = DBSTRING;

int count1; VARCHAR re1[20];

int re2;

int re3;

VARCHAR re4[60];

VARCHAR re5[20];

VARCHAR re6[2000];

VARCHAR re7[8];

EXEC SQL END DECLARE SECTION;

EXEC SQL INCLUDE sqlca; void sqlerror();

int getCgiParameter();

void setMemory ( void );

int cgiMain ( void )

{

int result;

putenv("ORACLE_HOME=/oracle/733");

putenv("ORACLE_SID=DB");

putenv("NLS_LANG=American_America.ko16ksc5601");

putenv("LD_LIBRARY_PATH=/oracle/733/lib");

EXEC SQL WHENEVER SQLERROR DO sqlerror();

EXEC ORACLE OPTION(HOLD_CURSOR=NO);

EXEC SQL CONNECT :username IDENTIFIED BY :password USING :dbstring;

cgiHeaderContentType("text/html");

setMemory(); // 변수초기화

getCgiParameter(); // html에서 받은 입력자료를 위에서 선언한 변수로 대입시켜주는 함수

EXEC SQL SELECT to_char(SYSDATE,'YY-MM-DD') into re7 from sys.dual;

EXEC SQL SELECT max(S_ID) INTO :count1 FROM s_reg_db order by s_date;

count1++;

EXEC SQL INSERT INTO s_reg_db ( s_id , s_name , s_age , s_sex , s_address , s_telephone , s_date , s_memo )

VALUES ( :count1, :re1 , :re2 , :re3 , :re4 , :re5, SYSDATE , :re6 );

fprintf(cgiOut, "Insert ok

");

fprintf(cgiOut, "끝!");

EXEC SQL COMMIT RELEASE; // commit을 한 후 연결을 계속 유지시킨다. 만약 EXEC SQL COMMIT하면 연결을 끊는다.

return 0;

}

void sqlerror()

{ // DB error 처리

EXEC SQL WHENEVER SQLERROR CONTINUE;

fprintf(cgiOut, "ORACLE Error detected:

");

fprintf(cgiOut, "% .70s

", sqlca.sqlerrm.sqlerrmc);

EXEC SQL ROLLBACK WORK RELEASE;

exit(1);

}

int getCgiParameter()

{

int result; char x[3];

result = cgiFormString ( "reg1", re1.arr , sizeof(re1.arr)); // reg1은 html에서 설정된 변수명

re1.len = strlen( (char *)re1.arr );

result = cgiFormString ( "reg4" , re4.arr , sizeof(re4.arr));

re4.len = strlen( (char *)re4.arr );

result = cgiFormString ( "reg5" , re5.arr , sizeof(re5.arr));

re5.len = strlen( (char *)re5.arr );

result = cgiFormString ( "reg6" , re6.arr , sizeof(re6.arr));

re6.len = strlen( (char *)re6.arr );

result = cgiFormString ( "reg2" , x , 3 );

re2 = atoi ( x ); result = cgiFormString ( "reg3" , x , 3 );

re3 = atoi ( x );

if ( result == cgiFormNotFound ) {

re3 = -1;

}

else {

re3 = atoi ( x );

}

fprintf(cgiOut," name : %s

",re1.arr);

fprintf(cgiOut," age : %d

",re2);

if ( re3 == 1 ) {

fprintf(cgiOut," sex : male

");

}

else if ( re3 == 2 ) {

fprintf(cgiOut," sex : female

");

}

fprintf(cgiOut," address : %s

",re4.arr);

fprintf(cgiOut," telephone : %s

",re5.arr);

fprintf(cgiOut,"memo : %s

",re6.arr);

}

void setMemory ( void )

{

memset(re1.arr,0,sizeof(re1.arr)); // memset을 이용하여 문자열변수(varchar2)들을 초기화 해준다.

memset(re4.arr,0,sizeof(re4.arr));

memset(re5.arr,0,sizeof(re5.arr));

memset(re6.arr,0,sizeof(re6.arr));

memset(re7.arr,0,sizeof(re7.arr));

re2 = -1; re3 = -1; count1 = 0; // 숫자변수 초기화

}

[html 문서의 구성]

...

...

[MakeFile의 구성]

Oracle 7.3.3 Version에서 사용하는 예제입니다.

include ../env_precomp.mk

.SUFFIXES: .pc .c .o

LDSTRING=

PRODUCT_LIBHOME=

MAKEFILE=Makefile

PROCPLSFLAGS= dbms=v6 PROCPPFLAGS= code=cpp $(CCPSYSINCLUDE)

USERID=myUserName/myPassWord

INCLUDE=$(I_SYM). $(PRECOMPPUBLIC)

CGILIBHOME=/home/superman/cgic // cgic library가 있는 디렉토리

EXECDIR=/www/superman/cgi-bin/ex1 // ex1.cgi를 저장시킬 디렉토리, 만약 현재 작업디렉토리에 그냥 두려면 안써도 무방하다.

CGILIB=-lcb -lcgic -lmy

TARGETS=ex1 // cgi를 만들 파일명 ex1과 ex2 2개의 cgi를 만들어야 한다면 TARGETs=ex1 ex2 하면 됩니다. ( 꼭 필요합니다!! )

# Rule to compile any program (specify EXE= and OBJS= on command line)

build: $(OBJS)

$(CC) -o $(EXE) $(OBJS) ./printTemplet.o -L$(LIBHOME) -L$(CGILIBHOME) $(PROLDLIBS) $(CGILIB) // Library연결 ( 자신이 프로그램에서 특별히 사용했던 Library를 연결

all: $(TARGETS)

$(TARGETS):

$(MAKE) -f $(MAKEFILE) build OBJS=$@.o EXE=$@.cgi

.pc.c:

$(PROC) $(PROCFLAGS) $(PROCPLSFLAGS) iname=$*.pc

.pc.o:

$(PROC) $(PROCFLAGS) $(PROCPLSFLAGS) iname=$*.pc

$(CC) $(CFLAGS) -c $*.c

.c.o:

$(CC) $(CFLAGS) -c $*.c install: mv *.cgi $(EXECDIR)

결국 당신이 제작한 ex1.pc 를 cgi로 만들려면 $make ex1 하면 ex1.cgi가 생성됩니다.

다음 이시간에는 Pro*C를 이용하여 WEB에서 List 뿌려주기를 만들어 봅시다.

from http://fordeveloper2.tistory.com/7008 by ccl(A) rewrite - 2020-03-07 03:22:10

댓글

이 블로그의 인기 게시물

HTML 13단계 - 폼(Form) 1탄

임시 인터넷 파일캐싱을 위한 방지 html,css,javascript

[C#]Log4Net 사용법