oracle embedded sql pro*c : chap 1 작 성 자 : 김선영 메 일 : 버 전 : 1.19 copyright by...
DESCRIPTION
Copyright by SunYoung Kim Pro*C environment Pro*C 란 ? C 언어 소스코드에 포함되는 Oracle 의 Embedded SQL 문을 해석하는 precompiler 환경을 의미. Pro*C 소스파일은.pc 확장자를 가지게 됨TRANSCRIPT
Oracle Embedded SQL
Pro*C : Chap 1
작 성 자 : 김선영
메 일 : [email protected]
버 전 : 1.19
Copyright by SunYoung Kim
Copyright by SunYoung Kim <[email protected]>
Preface Oracle 은 Oracle 의 등록상표입니다 .
Pro*C 는 Oracle 의 제품입니다 .
예제는 지면 제약상 한줄에 여러라인이 코딩될 수 있습니다 .
본 자료에 대한 질문사항은 연락처를 참고해주시기 바랍니다 .
E-mail address
Copyright by SunYoung Kim <[email protected]>
Pro*C environment Pro*C 란 ?
C 언어 소스코드에 포함되는 Oracle 의 Embedded SQL 문을 해석하는 precompiler 환경을 의미 .
Pro*C 소스파일은 .pc 확장자를 가지게 됨
Copyright by SunYoung Kim <[email protected]>
Pro*C environment (con't) What is Pro*C ?
Embedded SQL 문을 C 언어 소스코드내에 삽입하므로 직관적이다 .
두번의 컴파일 (.pc.c 와 .c.o 의 두번의 과정을 거침 ) 과정을 거친다 .
환경은 Pro*C precompiler ( 이하 proc), 헤더 , 라이브러리으로 구성된다 .
proc 는 Embedded SQL 문을 Oracle Library 의 API 로 교체한다 .
Copyright by SunYoung Kim <[email protected]>
Pro*C environment (con't) pcscfg.cfg
default configuration file (has default options)
$ORACLE_HOME/precomp/admin/pcscfg.cfg
각종 옵션들은 proc 실행시 오버라이딩 될 수 있음
sys_include=(/usr/include,/usr/lib/gcc-lib/i386-redhat-linux/3.3.4/include,/u01/app/oracle/db_1/precomp/public,/u01/app/oracle/db_1/network/public,/u01/app/oracle/db_1/plsql/public)ltype=short
Copyright by SunYoung Kim <[email protected]>
Pro*C environment (con't) required environment variables
ORACLE_BASE
» oracle 제품군이 설치된 곳
ORACLE_HOME
» oracle DB 가 설치된 곳
LD_LIBRARY_PATH
» 오라클의 동적 라이브러리를 추가해줘야 함
ORACLE_SID
» 현재 사용할 데이터베이스 SID
Copyright by SunYoung Kim <[email protected]>
Pro*C environment (con't) 환경 설정 예 (sh 쉘 문법에 맞추어 ...)
ORACLE_BASE=/u01/app/oracleORACLE_HOME=$ORACLE_BASE/product/10.1.0/db_1ORACLE_SID=sunyPATH=$ORACLE_HOME/bin:$PATH
if [ "x$LD_LIBRARY_PATH" = "x" ]; thenLD_LIBRARY_PATH=/usr/lib:$ORACLE_HOME/lib:$HOME/libelseLD_LIBRARY_PATH=/usr/lib:$ORACLE_HOME/lib:$LD_LIBRARY_PATHfi
export PATH LD_LIBRARY_PATHexport ORACLE_BASE ORACLE_HOME ORACLE_SID
Copyright by SunYoung Kim <[email protected]>
Options proc 주요 옵션들
include : 헤더를 찾을 위치를 더한다 .
» include="../include" include="$(MYPROJ_DIR)/inc"
» include="(../include, $(MYPROJ_DIR)/inc)"
sys_include : 시스템 기본 헤더위치 (/usr/include) 를 변경할때 사용됩니다 .
define : 전처리기의 매크로를 proc 에서 지정할 수 있습니다 .
Copyright by SunYoung Kim <[email protected]>
Options (con't) proc 주요 옵션들
iname : 입력파일명
» iname=hello.pc
oname : 출력파일명
» oname=hello.c
ltype : list file 의 데이터양을 결정 ( 에러 및 출력을 볼 수 있음 )
» value : none, short, long
Copyright by SunYoung Kim <[email protected]>
Options (con't) sqlcheck : pc 파일의 Embedded SQL 문을 검증합니다 . 기본값은 syntax 입니다 .
» sqlcheck=syntax : 문법만 검사합니다 .
» sqlcheck=semantics : 의미만 검사합니다 .( 단어의 개수정도만 )
» sqlcheck=full : 실제로 SQL 을 수행하여 검증합니다 . (userid 옵션을 필요로 함 )
userid : sqlcheck 를 행하기 위해서 DB 에 접근하기 위한 유저명 / 패스워드
» userid=scott/tiger
def_sqlcode : sqlca.sqlcode 를 SQLCODE 로 맵핑시켜줍니다 . 따라서 #define 을 이용하여 매크로 지정할 필요가 없어집니다 . 기본값은 no 입니다 .
» def_sqlcode=yes
Copyright by SunYoung Kim <[email protected]>
Options (con't) char_map : 배열이나 문자열을 맵핑할 때 어떤 방식을 사용할지 결정합니다
» char_map=charz : 배열사용 ( 남은 공간은 공백문자로 )
» char_map=string : 널종료 문자열로 맵핑
maxopencursors : 최대로 열수 있는 커서의 수를 지정 . 기본값은 10.
hold_cursor : cursor cache 에 저장된 상태로 있도록 함 .
» 동일한 SQL 구문을 여러번 사용할때 cache 에 저장되었다면 구문 분석 시간을 줄일 수 있음 . 기본값은 no.
Copyright by SunYoung Kim <[email protected]>
Options (con't) release_cursor : cursor 가 cache 에서 해제되도록 지정함 . 기본값은 no.
prefetch : 커서 open 시 미리 가져올 row 개수 , 기본값은 1.
thread : 멀티쓰레드 환경 지정 , 기본값은 no
unsafe_null : NULL 컬럼을 fetch 할때 indicator 변수가 지정되어있지 않아도 ORA-1405 에러를 발생시키지 않게 함 .
lines : __LINE__ 을 pc 파일의 라인번호로 교체 . 기본값은 no
proc 그외의 사항
*.dcl *.cod *.cud *.lis 파일은 proc 가 precompile 하면서 생성되는 부수적인 파일
Copyright by SunYoung Kim <[email protected]>
Invalid options Pro*C 설치후 종종 발생되는 에러
include 경로 위치 탐색 실패 -> pcscfg.cfg 수정 혹은 프롬프트 옵션 include 사용
$ makePro*C/C++: Release 10.1.0.3.0 - Production on Mon Jan 10 18:02:38 2005Copyright (c) 1982, 2004, Oracle. All rights reserved.Error at line 0, column 0 in file proc_conn.pcPCC-S-02201, Encountered the symbol "<eof>" when expecting one of the following: ; : an identifier, end-exec, random_terminalError at line 0, column 0 in file proc_conn.pcPCC-F-02102, Fatal error while doing C preprocessingError at line 34, column 11 in file /usr/include/stdio.h 34 # include <stddef.h> 34 ..........1
34 PCC-S-02015, unable to open include file
Copyright by SunYoung Kim <[email protected]>
EXEC SQL directive Embedded SQL 지시어 : EXEC SQL
C 소스코드내에 삽입함 . 문법은 SQL 표준 문법을 따름 .
EXEC SQL 로 시작하고 세미콜론 (;) 으로 끝마침
CPP (C Pre-Processor) 가 제공하는 매크로 구문은 사용할 수 없음 .
C API 함수를 직접 호출할 수 없음
SQL 문은 관습적으로 대문자로 기입 (But, SQL 문은 대소문자를 구별하지는 않음 )EXEC SQL ... (생략 ) ... ;
memcpy(.....);
if ( ... ) {
... (생략 ) ...;
}
EXEC SQL ... (생략 ) ... ;
Copyright by SunYoung Kim <[email protected]>
variables on Pro*C 호스트변수 (host variable)
오라클 데이터베이스와 C 프로그램 사이에 데이터를 교환하는 목적으로 사용
char, char [], short, int, long, float, double, VARCHAR [] 를 사용가능함
Embedded SQL 안에서 호출시에는 콜론 (:) 을 접두어 (prefix) 로 사용함 .
BEGIN DECLARE SECTION 으로 시작하고 , END DECLARE SECTION 으로 끝마침(생략 가능함 )
문자열의 경우에는 데이터베이스의 스키마보다 1 바이트 많아야 함 ( 널종료 )
호스트변수에는 register storage-class 지시자를 사용할 수 없음 .
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR[100] va_name;
int i_deptno;
EXEC SQL END DECLARE SECTION;
Copyright by SunYoung Kim <[email protected]>
variables on Pro*C (con't) VARCHAR 호스트변수 사용
VARCHAR [] 형은 arr 과 len 의 두개의 멤버를 가짐
» arr : 문자열 데이터가 저장되는 실제 공간 (n byte 의 공간 )
» len : arr 멤버의 길이를 지정 (2 byte)
int i_idnum, i_age;
VARCHAR vc_name[20];
EXEC SQL SELECT NAME, AGE
INTO :vc_name, :i_age
FROM E_MEMBERS
WHERE IDNUM = :i_idnum;
printf("Name (%.*s) Age (%d)\n", vc_name.len, vc_name.arr, i_age);
Copyright by SunYoung Kim <[email protected]>
Connect to DB CONNECT 지시어
CONNECT <userid> IDENTIFIED BY <passwd> [USING <dbstring>]
연결 수행은 userid, passwd 을 필요로 함
정상적으로 연결되면 그 후에는 Embedded SQL 문으로 DB 에 작업 가능함
/* "sqlca.sqlcode" is usually defined to be the SQLCODE */
char *p_userid = "scott", *p_passwd="tiger";
EXEC SQL CONNECT :p_userid IDENTIFIED BY :p_passwd;
if ( SLQCODE != 0 ) {
/* 에러처리 */}
Copyright by SunYoung Kim <[email protected]>
Transaction COMMIT or ROLLBACK 지시어
<COMMIT | ROLLBACK> [WORK]
COMMIT WORK 는 현재 작업을 반영함 ROLLBACK WORK 는 현재 작업을 버림 COMMIT 하지 않고 그냥 프로그램을 종료하면 ROLLBACK 처리 됨 .
EXEC SQL COMMIT WORK;
EXEC SQL ROLLBACK WORK;
Copyright by SunYoung Kim <[email protected]>
Disconnect RELEASE 지시어
<COMMIT | ROLLBACK> [WORK] RELEASE
현재 데이테베이스 연결에 속한 모든 자원을 해제함 = 연결 종료
잦은 연결 시작 / 종료는 시스템에 부담을 가중시킴 , 그러나 너무 사용하지 않는 연결을 유지하면 시스템 자원 낭비가 될 수 있음
EXEC SQL COMMIT WORK RELEASE;
EXEC SQL ROLLBACK WORK RELEASE;
Copyright by SunYoung Kim <[email protected]>
Example data Scheme
WHENEVER SQLERROR CONTINUE;DROP SEQUENCE E_MEMBER_SEQ;CREATE SEQUENCE E_MEMBER_SEQ INCREMENT BY 1 START WITH 1 NOCYCLE NOCACHE;DROP TABLE E_MEMBERS CASCADE CONSTRAINTS;CREATE TABLE E_MEMBERS ( IDNUM NUMBER(4) NOT NULL, NAME VARCHAR(20) NOT NULL, AGE NUMBER(3) DEFAULT 0 NOT NULL, DESCRIPT VARCHAR(512) DEFAULT 'NOTHING' NOT NULL, PRIMARY KEY (IDNUM, NAME));
Copyright by SunYoung Kim <[email protected]>
Example data (con't)INSERT INTO E_MEMBERS VALUES (E_MEMBER_SEQ.NEXTVAL,'Michael',21,'Guard');... (E_MEMBER_SEQ.NEXTVAL, 'Smith', 44, 'Analyst');... (E_MEMBER_SEQ.NEXTVAL, 'Lily', 28, 'Staff');... (E_MEMBER_SEQ.NEXTVAL, 'Dave', 22, 'Assistant Staff');... (E_MEMBER_SEQ.NEXTVAL, 'Duke', 39, 'Manager');... (E_MEMBER_SEQ.NEXTVAL, 'Kerry', 23, 'Staff');... (E_MEMBER_SEQ.NEXTVAL, 'Raymond', 24, 'Assistant Staff');... (E_MEMBER_SEQ.NEXTVAL, 'Kenny', 35, 'Manager');... (E_MEMBER_SEQ.NEXTVAL, 'Corssiado', 32, 'Staff');... (E_MEMBER_SEQ.NEXTVAL, 'Steven', 35, 'Assistant Manager');... (E_MEMBER_SEQ.NEXTVAL, 'Ryo', 27, 'Staff');... (E_MEMBER_SEQ.NEXTVAL, 'Zhang', 26, 'Guard');... (E_MEMBER_SEQ.NEXTVAL, 'Maoweui', 27, 'Guard');... (E_MEMBER_SEQ.NEXTVAL, 'Daniel', 41, 'Vice President');... (E_MEMBER_SEQ.NEXTVAL, 'Ron', 23, 'Clerk');
Copyright by SunYoung Kim <[email protected]>
Example: Embedded SQL SQL 문 수행예제 1 : pr1.pc
#include <stdio.h>#include <stdlib.h>#include "sqlca.h"#define SQLCODE sqlca.sqlcodeint main(int argc, char *argv[]){ int n_maxidnum; if (argc < 2) { printf("Usage : %s <username> <passwd>\n", argv[0]); return EXIT_SUCCESS; }
Copyright by SunYoung Kim <[email protected]>
Example: Embedded SQL (con’t) SQL 문 수행예제
EXEC SQL CONNECT :argv[1] IDENTIFIED BY :argv[2]; /* connect */ if (SQLCODE != 0) { /* error */ fprintf(stderr, "FAIL: CONNECT\n"); exit(EXIT_FAILURE); } EXEC SQL SELECT MAX(IDNUM) INTO :n_maxidnum FROM E_MEMBERS; if (SQLCODE != 0) { /* error */ } printf("Max IDNUM : %d\n", n_maxidnum); EXEC SQL COMMIT WORK RELEASE; /* disconnect */ return EXIT_SUCCESS;}
Copyright by SunYoung Kim <[email protected]>
Running example HOWTO 1) precompile with proc
proc char_map=string ltype=none iname=pr1.pc oname=pr1.c
2) cc 로 compile
cc -Wall -I$ORACLE_HOME/precomp/public -I$ORACLE_HOME/network/public \-I$ORACLE_HOME/plsql/public -c -o pr1.o pr1.c
3) cc 로 링킹
cc pr1.o -L$ORACLE_HOME/lib -lclntsh -o pr1
4) 실행
./pr1 scott tiger
Copyright by SunYoung Kim <[email protected]>
Running example HOWTO (con't) 잘못된 compile 작업으로 인한 오류 주의 !!!
현상 : ECPGget_sqlca 등과 같이 잘못된 심볼을 찾으려 함
해결 :
» compile 시 include directory 를 지시하는 -I 옵션 ( 대문자 i) 이 잘못주어짐
$ cc -L$ORACLE_HOME/lib -lclntsh pr1.o -o pr1... cannot find reference to ECPGget_sqlca ...
Copyright by SunYoung Kim <[email protected]>
Example: Embedded SQL (con’t) SQL 문 수행예제 2 ( 연습 )
사용자에게서 IDNUM 를 입력받아 name, age 필드를 검색 / 출력하는 아래 코드를참고하여 프로그램을 완성하라 .
int main(int argc, ... char c_str[10]; int i_idnum; short i_age; VARCHAR vc_name[20];...생략 ...
memset(c_str, 0, sizeof(c_str)); if (fgets(c_str, sizeof(c_str), stdin) == NULL) { exit(1) } i_idnum = atoi(c_str); EXEC SQL SELECT NAME, AGE INTO :vc_name, :i_age FROM E_MEMBERS WHERE IDNUM = :i_idnum;...생략 ...
Copyright by SunYoung Kim <[email protected]>
Example: Embedded SQL (con’t) SQL 문 수행예제 3 ( 연습 )
사용자에게서 NAME, AGE, DESC 를 입력받아 테이블에 추가하도록 한다 .
struct e_member { int idnum; char name[20+1]; short age; char desc[512+1];};int input_elem(struct e_member *s); int main(int argc, char *argv[]){ struct e_member em;...생략 ...
Copyright by SunYoung Kim <[email protected]>
Example: Embedded SQL (con’t) SQL 문 수행예제 3 ( 연습 )
memset(&em, 0, sizeof(struct e_member)); EXEC SQL SELECT E_MEMBER_SEQ.NEXTVAL INTO :em.idnum FROM DUAL; input_elem(&em); EXEC SQL INSERT INTO E_MEMBERS (IDNUM, NAME, AGE, DESCRIPT) VALUES (:em.idnum, :em.name, :em.age, :em.desc);... 생략 ...}int input_elem(struct e_member *s){ printf("Input (Name Age Desc)\n"); scanf("%s %d %s", s->name, &s->age, s->desc); return 0;}
Copyright by SunYoung Kim <[email protected]>
Compile with make Makefile 규칙
make 의 suffix rule 이나 GNU make 의 implicit rule 을 이용해서 작성 가능함
PROC := proc
PROC_INC := include="$(PREFIX)/include"
PROC_FLAGS := char_map=string select_error=yes sqlcheck=full
%.c: %.pc
$(PROC) $(PROC_INC) $(PROC_FLAGS) iname=$< oname=$@
PROC := procPROC_INC := include="$(PREFIX)/include"PROC_FLAGS := char_map=string select_error=yes sqlcheck=full
.SUFFIXES: .pc
.pc.c:
$(PROC) $(PROC_INC) $(PROC_FLAGS) iname=$< oname=$@
Copyright by SunYoung Kim <[email protected]>
Compile with make (con't) Pro*C 의 .c.o 의 규칙
기본 suffix rule 이나 implicit rule 을 사용함
CC (C Compiler), CPPFLAGS (C Pre-Processor Flags), CFLAGS (Compiler Flags) 를 지정해두어 사용함
CPPFLAGS += -I$(ORACLE_HOME)/precomp/public \ -I$(ORACLE_HOME)/network/public \ -I$(ORACLE_HOME)/plsql/public
# default implicit rule for C compiling
#%.o: %.c
# $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
Copyright by SunYoung Kim <[email protected]>
Compile with make (con’t) General Makefile for Pro*C
OUT := my_test1 my_test2CC := ccCFLAGS := -Wall –g
# for Pro*CPROC := procPROC_INC := include="($(PREFIX)/include)"
CPPFLAGS += -I$(ORACLE_HOME)/precomp/public \ -I$(ORACLE_HOME)/network/public \ -I$(ORACLE_HOME)/plsql/publicLOADLIBES += -L$(ORACLE_HOME)/libLDLIBS += -lclntshPROC_FLAGS:= char_map=string ltype=short sqlcheck=syntax
%.c : %.pc$(PROC) $(PROC_INC) $(PROC_FLAGS) iname=$< oname=$@
all: $(OUT)clean:
$(RM) $(OUT) $(patsubst %.pc,%.c,$(wildcard *.pc)) *.o tp*