2014년 8월 21일 목요일

proc로 cgi만들기(1) - 김태양[오라클개발자교육/오라클/ORACLE강좌/오라클교육잘하는곳/오라클교육추천/ORACLE실무교육/ORACLE/ORACLE교육/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 <stdio.h> 

#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 

<ex1.pc> :  

#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\n");  

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: \n"); 

fprintf(cgiOut, "% .70s \n", 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 \n\n",re1.arr); 

fprintf(cgiOut," age : %d\n\n",re2);  

if ( re3 == 1 ) { 

fprintf(cgiOut," sex : male\n");  



else if ( re3 == 2 ) { 

fprintf(cgiOut," sex : female\n"); 



fprintf(cgiOut," address : %s\n\n",re4.arr); 

fprintf(cgiOut," telephone : %s\n\n",re5.arr); 

fprintf(cgiOut,"memo : %s\n\n",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 문서의 구성] 

<html> 

<body> 

<form action=/cgi-bin/exam.cgi method=post> 

<input type=text name=re1> 

... 

... 

<input type=submit value="완료"> 

</form> 





[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 뿌려주기를 만들어 봅시다.



평일주간[100%환급과정]
(8/25)C#4.0,WinForm,ADO.NET
(8/25)안드로이드개발자과정
(8/25)SQL기초에서 Schema Object까지
(8/29)Spring,MyBatis,Hibernate실무과정
(8/29)자바기초JDBC,Servlet/JSP까지
(8/29)PL/SQL,ORACLE HINT,TUNING
(8/25)오라클자바채용확정교육
평일야간[개인80%환급]
(8/26)SQL기초에서실무까지
(8/26)안드로이드개발자과정
(8/28)자바JSP,jQuery,Spring,MyBatis
(8/29)Spring, MyBatis, Hibernate
(9/02)HTML5,CSS3,Ajax,jQuery마스터
(9/12)C#,Network,ADO.NET,ASP.NET
주말주간[개인80%환급]
(8/23)자바웹&스프링,마이바티스
(8/23)Spring, MyBatis, Hibernate
(8/23)SQL기초에서실무까지
(8/23)자바,네트워크,웹&스프링
(8/30)안드로이드개발자과정
(8/30)C#,ASP.NET마스터(8/30)웹퍼블리싱 마스터

댓글 없음:

댓글 쓰기