- 전체
- Sample DB
- database modeling
- [표준 SQL] Standard SQL
- G-SQL
- 10-Min
- ORACLE
- MS SQLserver
- MySQL
- SQLite
- postgreSQL
- 데이터아키텍처전문가 - 국가공인자격
- 데이터 분석 전문가 [ADP]
- [국가공인] SQL 개발자/전문가
- NoSQL
- hadoop
- hadoop eco system
- big data (빅데이터)
- stat(통계) R 언어
- XML DB & XQuery
- spark
- DataBase Tool
- 데이터분석 & 데이터사이언스
- Engineer Quality Management
- [기계학습] machine learning
- 데이터 수집 및 전처리
- 국가기술자격 빅데이터분석기사
- 암호화폐 (비트코인, cryptocurrency, bitcoin)
ORACLE [oracle] [pro-c] pro*C (프로씨) 프로그래밍
2023.09.08 01:53
[oracle] [pro-c] pro*C (프로씨) 프로그래밍
+++++++++++
ProC...
+++++++++++
-. 오라클 데이타베이스 내의 테이블에 존재하는 레코드들을 조회,수정 등의 데이타 처리를 하고, C프로그램으로 전환하기 위해 사용함.
-. C와의 차이점
-. 외형상의 차이 : 확장자가 .pc로 끝난다.
-. 기본적으로 C문법을 따르며, C프로그램코드에 DB에 접속하여 레코드들을 처리하는 과정이 추가되어 작성된다.
즉, C로 작성된 프로그램코드에 오라클의 SQL의 DML or DDL명령문이 'EXEC'구문과 결합된 형태가 추가된 것임을 알 수 있다.
-. 변수선언에서 C언어에서는 사용하지 않는, .arr과 .len이라는 변수가 컴파일된 C source코드에 생성되어 있는 것을 확인할 수 있다.
-. 컴파일 과정
-. filename.pc -> filename.c -> filename.o -> filename*(생성된 오브젝트 파일을 링크해서 실행파일을 만드는 과정이다.)
-. 실제 컴파일
-. makefile 위치
$ORACLE_HOME에 proc/에 보면 proc.mk파일이 있다.
이중에서
1) USERID = uinfo/mation
-. 오라클 DB에 접속할때 사용할 사용자 아이디와 비밀번호 지정
2) DEST = /home/elfsun/simple/bin
-. 컴파일후 실행파일을 복사할 디렉토리
3) COMM_OBJ = /home/elfsun/simple/lib/lib1.o\
/home/elfsun/simple/lib/lib2.o\
/home/elfsun/simple/lib/lib3.o\
/home/elfsun/simple/lib/lib4.o
-. 컴파일시 참조로할 오브젝트 파일들.
\(백슬레시)로 구분함.
4) all : $(PROGRAM)
-. 프로그램의 이름을 지정할 수 있다. 이것은 프로그램의 소스 이름이 되며, 컴파일후 생성될 실행 파일의 이름이 되기도 한다.
5) install :
-. 컴파일후 생성된 실행 파일을 복사해주는 작업을 수행
6) clean :
-. 컴파일 과정에서 생성되는 C파일과 오브젝트 파일들을 삭제할때 수행
이들중 수행할 각 명령들은 '@'바로 뒤에 작성해 줄 수 있다.
[실제 컴파일 수행 - makefile이름이 proc.mk인 경우]
1) 실제 컴파일을 하기 위해
$ make -f proc.mk
2) 컴파일한 실행 파일을 ~/bin/ 디렉토리에 복사하기 위해
$ make -f proc.mk install
3) 컴파일 후 생성되는 오브젝트 파일과 c파일을 삭제하기 위해
$ make -f proc.mk clean
-. SQLCA관련 변수들...
-. sqlca.sqlerr[0] : fetch를 사용하여 쿼리된 레코드의 건수를 리컨시켜 주는 역할을 하는 변수이다.
-. sqlca.sqlwarn : 경고에 대한 정보들을 지니고 있는 변수이다.
-. sqlca.sqlerrm.sqlerrmc : sql 명령수행중 에러가 발생했을때, 발생한 에러에 대한 내용과 오류 코드번호에 관한 정보를 출력시켜 준다.
---------------------------------------
-. sqlca.sqlcode값 내 용
---------------------------------------
0 sql문이 정상적으로 수행
1403 유일하게 양수값을 갖는 에러코드임.
조건에 맞는 데이타가 하나도 없을때.
-1405 조회된 값중 null값이 있을때
---------------------------------------
-. host변수 선언
-. 호스트변수는 데이타베이스에서 데이타 처리 결과를 저장하기 위해 사용되며, 응용 프로그램내에서는
변수로서의 역할을 한다. 따라서 호스트 변수를 선언할 때에는 데이타베이스 내에서 사용되는 칼럼의
데이타 타입과 그 크기를 고려하여 선언되어야 하며, 프리컴파일 과정을 통해 응용프로그램내에서도
사용가능한 형태이어야 한다.
ex)
EXEC SQL BEGIN DECLARE SECTION;
varchar username[16], userarea[10];
int usrno, usrage;
EXEC SQL END DECLARE SECTION;
[주의]
1) 호스트 변수 선언시에 오라클 예약어를 사용하지 말것.
2) 호스트 변수에서는 null처리를 해주지 않기 때문에 응용 프로그램에서 반드시 null처리를 해주어야 한다.
단, 호스트 변수가 숫자형인 경우에는 예외이다.
-. DB접속
방법1>
EXEC SQL CONNECT elfsun
INDENTIFIED BY 1234;
방법2>
EXEC SQL BEGIN DECLARE SECTION;
varchar userid[8], passwd[8];
EXEC SQL END DECALRE SECTION;
strncpy(userid.arr,"elfsun",6);
strncpy(passwd.arr,"1234",4);
EXEC SQL CONNECT :userid;
IDENTIFIED BY :passwd;
-. 일반적으로 방법2를 더 선호함.
-. 방법2를 쓸때에 변수명 앞에는 반드시 :를 붙여서 사용하고 있는 변수가 호스트 변수임을 명시해야 한다.
-. CURSOR이용 : 쿼리문으로 조회되는 레코드가 한 건 이상일때 사용함.
형식>
1) EXEC SQL PREPARE statement FROM variable; (쿼리하고자 하는 sql문장 정의)
2) EXEC SQL DECLARE cursor_name CURSOR FOR statement; ( 사용할 커서 선언 )
3) EXEC SQL OPEN cursor_name; ( 선언한 커서 열기 )
4) EXEC SQL FETCH cursor_name INTO :host_variable1, :host_variable2, :host_variable3, ....; ( 열어둔 커서 실행 )
5) EXEC SQL CLOSE cursor_name; ( 열었던 커서 닫음 )
1) EXEC SQL PREPARE statement FROM variable; (쿼리하고자 하는 sql문장 정의)
ex)
char SqlCmd[100]; (변수 SqlCmd를 선언)
memset(SqlCmd,0x00,sizeof(SqlCmd)); ( memset함수를 이용하여 초기화 작업함)
sprintf(SqlCmd,"SELECT usrno, usrname, usrarea FROM forumlist"); (쿼리문을 SqlCmd에 대입함)
EXEC SQL PREPARE st_1 from :SqlCmd; (EXEC..문장을 이용하여 쿼리할 구조를 정의함)
2) EXEC SQL DECLARE cursor_name CURSOR FOR statement; ( 사용할 커서 선언 )
형식1>
EXEC SQL DECLARE cursor_name CURSOR FOR statement;
형식2>
EXEC SQL DECLARE cursor_name CURSOR FOR select 문장;
-. cursor_name : 사용할 커서명
ex)
EXEC SQL DECLARE CUR_1 CURSOR FOR ST_1; (ST_1은 PREPARE에서 정의한것과 동일해야 함)
EXEC SQL DECLARE CUR_1 CURSOR FOR select usrno, username, userarea From forumlist;
3) EXEC SQL OPEN cursor_name; ( 선언한 커서 열기 )
ex)
EXEC SQL OPEN CUR_1;
4) EXEC SQL FETCH cursor_name INTO :host_variable1, :host_variable2, :host_variable3, ....; ( 열어둔 커서 실행 )
ex)
EXEC SQL BEGIN DECLARE SECTION;
varchar usrname[16], usrarea[10];
int usrno;
EXEC SQL END DECLARE SECTION;
......
EXEC SQL FETCH CUR_1 INTO :usrno, :usrname, :userarea;
-. 여기서 사용하는 조회된 칼럼들과 1대1로 대응되어야 한다.
또한 사용될 호스트 변수들은 이미 이전에 선언이 되어 있어야만 사용이 가능하다. 칼럼의 데이타 타입과 크기가
일치해야함에도 주의.
5) EXEC SQL CLOSE cursor_name; ( 열었던 커서 닫음 )
ex)
EXEC SQL CLOSE CUR_1;
-. 오류 처리
1) whenever sqlerror 구문
형식)
① EXEC SQL WHENEVER SQLERROR GOTO stop_st;
② EXEC SQL WHENEVER SQLERROR GOTO STOP;
③ EXEC SQL WHENEVER SQLERROR GOTO CONTINUE;
-. 위 문장들은 SQL문장의 수행 결과 리턴되는 sqlca.sqlcode의 값이 음수로서, 에러를 발생시키는 경우, 더이상
프로그램을 진행시키지 않도록 stop_st루틴(①번에 해당)으로 분기하여 프로그램의 에러처리를 하도록 하는 문장임.
stop_st대신 STOP나 CONTINUE를 쓰기도 한다.
-. 또한 실행시켰던 SQL문장들이 레코드의 값 자체의 변경과 관련이 있는 문장들, 즉 INSERT, DELETE, UPDATE와 같은
SQL문장들이었다면, 'EXEC SQL ROLLBACK WORK'명령을 이용하여 그 트렌잭션을 취소시키는 과정을 추가해 주어야 한다.
2) whenever not found 구문
형식)
EXEC SQL WHENEVER NOT FOUND GOTO stop_st;
EXEC SQL WHENEVER NOT FOUND STOP;
EXEC SQL WHENEVER NOT FOUND CONTINUE;
-. 위 문장들은 SQL문장 실행 결과 sqlca.sqlcode값이 1403으로 조건에 맞는 레코드 건수가 하나도 없는 경우이다.
-. ProC내에서의 select 문장
ex1)
-------------------------------------------------------------
EXEC SQL BEGIN DECALRE SECTION;
varchar usrname[16], usrarea[10];
int usrno;
EXEC SQL END DECLARE SECTION;
EXEC SQL SELECT usrno, usrname, usrarea
INTO : usro, :usrname, :usrarea
FROM forumlist
WHERE usrno=5;
EXEC SQL WHENEVER SQLERROR GOTO stop_st;
EXEC SQL COMMIT WORK;
printf("\n 회원의 고유번호 =%d",usrno);
printf("\n 회원의 이름 =%d",usrname.arr);
printf("\n 회원의 이름(크기) =%d BYTE", usrname.len);
printf("\n 회원의 거주지역 =%s", usrarea.arr);
printf("\n 회원의 거주지역(크기) =%d BYTE", usrarea.len);
stop_st :
printf("\n 에러메시지 =%s", sqlca.sqlerrm.sqlerrmc);
-------------------------------------------------------------
-. into 구문은 쿼리 결과에 만족하는 데이타를 검색해 와서 into구문 뒤의 변수에 각각 할당한다.
-. 호스트 변수명 앞에 (:)을 붙여 줌으로써 조회할 테이블이 칼럼명과 구분을 지어 준다.
ex2)
-------------------------------------------------------------
EXEC SQL BEGIN DECALRE SECTION;
varchar usrname[16], usrarea[10];
int usrno;
char SqlCmd[100];
EXEC SQL END DECLARE SECTION;
memset(SqlCmd,0x00,sizeof(SqlCmd));
sprintf(Sqlcmd,"select usrno, usrname, usrarea from forumlist");
EXEC SQL PREPARE ST_1 FROM :SqlCmd;
EXEC SQL DECLARE CUR_1 FOR ST_1;
EXEC SQL OPEN CUR_1;
EXEC SQL FETCH SUR_1 INTO :usrno, :usrname, :usrarea;
if (sqlca.sqlcode < && sqlca.sqlcode != -1405)
{
printf("\n 에러메시지 = %s", sqlca.sqlerrm.sqlerrmc);
printf("\n 레코드 조회시 에러 발생!");
EXEC SQL CLOSE CUR_1;
EXEC SQL ROLLBACK WORK;
exit();
} /* error */
else if(sqlca.sqlcode == 1403)
{
printf("\n 에러메시지 ="%s", sqlca.sqlerrm.sqlerrmc);
printf('\n 조건에 맞는 데이타가 없슴다!");
EXEC SQL CLOSE CUR_1;
EXEC SQL ROLLBACK WORK;
exit();
} /* not exist */
while(sqlca.sqlcode ==0)
{
printf("\n 회원의 고유번호 =%d",usrno);
printf("\n 회원의 이름 =%d",usrname.arr);
printf("\n 회원의 이름(크기) =%d BYTE",usrname.len);
printf("\n 회원의 거주지역 =%s", usrarea.arr);
printf("\n 회원의 거주지역(크기) =%d BYTE", usrarea.len);
EXEC SQL FETCH CUR_1 INTO :usrno, :usrname, :usrarea;
} /* while */
printf("\n 오라클 메시지 = %s",sqlca.sqlerrm.sqlerrmc);
printf("\n 레코드가 성공적으로 조회되었습니다.");
EXEC SQL CLOSE CUR_1;
EXEC SQL COMMIT WORK;
-------------------------------------------------------------
-. PROC속의 UPDATE문장
-----------------------------------------------------------------------------
ex1)
EXEC SQL BEGIN DECLARE SECTION;
varchar username[16], usrarea[10];
int usrno;
EXEC SQL END DECLARE SECTION;
EXEC SQL SELECT usrno, username, usrarea
into :usrno, :usrname, :usrarea
from forumlist
where usrno=3;
EXEC SQL WHENEVER SQLERROR GOTO stop_st;
printf("\n 변경전 회원[%d]번의 거주지역 =[%s]",usrno,usrarea.arr);
EXEC SQL COMMIT WORK;
strcpy(userarea.arr,"SEOUL");
usrarea.len =5;
EXEC SQL UPDATE FORUMLIST
SET usrarea =:usrarea
WHERE usrno =3;
EXEC SQL WHENEVER SQLERROR GOTO stop_st;
EXEC SQL COMMIT WORK;
printf("\n 오라클 메시지 =%s",sqlca.sqlerrm.sqlerrmc);
EXEC SQL SELECT usrno,usrarea
INTO :usrno, :usrarea
FROM forumlist
WHERE usrno=3;
EXEC SQL WHENEVER SQLERROR GOTO stop_st;
printf("\n 변경후의 회원 [%d]번의 거주지역 =[%s]", usrno.usrarea.arr);
EXEC SQL COMMIT WORK;
exit();
stop_st:
EXEC SQL ROLLBACK WORK;
printf("\n 에러발생 =%s",sqlca.sqlerrm.sqlerrmc);
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
ex2)
EXEC SQL BEGIN DECLARE SECTION;
varchar usrname[16], usrarea[10];
int usrno;
EXEC SQL END DECLARE SECTION;
char SqlCmd[100];
EXEC SQL select usrno,username,usrarea
into :usrno, :usrname, :usrarea
from forumlist
where usrno=3;
EXEC SQL WHENEVER SQLERROR GOTO stop_st;
printf("\n 변경전의 [%d]번째 회원의 거주지역 =[%s]", usrno, usrarea.arr);
EXEC SQL COMMIT WORK;
memset(SqlCmd,0x00,sizeof(SqlCmd));
sprintf(SqlCmd,"UPDATE FORUMLIST set usrarea=%s \ (한 문장이 끝나지 않았기 때문에 \(역슬래시)를 사용함)
where usrno=3","seoul");
EXEC SQL EXCUTE IMMEDIATE :SqlCmd;
EXEC SQL WHENEVER SQLERROR GOTO stop_st;
EXEC SQL COMMIT WORK;
EXEC SQL select usrno, usrarea
into :usrno, :usrarea
from forumlist
where usrno=3;
EXEC SQL WHENEVER SQLERROR GOTO stop_st;
printf("\n 변경후의 [%d]번째 회원의 거주지역 =[%s]", usrno,usrarea.arr);
EXEC SQL COMMIT WORK;
exit();
stop_st:
EXEC SQL ROLLBACK WORK;
printf("\n 에러 메시지 =%s", sqlca.sqlerrm.sqlerrmc);
-----------------------------------------------------------------------------
-. 위의 update문을 약간 수정하면
sprintf(SqlCmd,"update forumlist set userarea=%s where usrno=%d","seoul",3);로 해도 됨.
-. ProC속의 Insert문장
-----------------------------------------------------------------------------
ex1)
EXEC SQL BEGIN DECLARE SECTION;
varchar usrname[16], usrarea[10], usrkindcode[4];
int usrno ;
EXEC SQL END DECLARE SECTION;
int tot;
tot =0;
usrno=10;
strncpy(usrname.arr,"LEE-Y-S",Strlen("LEE-Y-S"));
strncpy(usrarea.arr,"seoul",strlen("seoul"));
strncpy(usrkindcode,"1004",strlen("1004"));
EXEC SQL INSERT INTO FORUMLIST(usrno, usrname, usrarea, usrkindcode)
values(:usrno, :usrname, :usrarea, :usrkindcode);
EXEC SQL WHENEVER SQLERROR GOTO stop_st;
printf("\n insert success!!");
printf("\n 오라클 메시지 = %s", sqlca.sqlerrm.sqlerrmc);
EXEC SQL SELECT COUNT(*)
INTO :TOT
FROM FORUMLIST
EXEC SQL WHENEVER SQLERROR GOTO stop_st;
printf("\n forumlist 테이블에 존재하는 총 회원 수 =%d", tot);
EXEC SQL COMMIT WORK;
EXEC SQL SELECT usrno, usrarea
INTO :usrno, :usrarea
FROM FORUMLIST
WHERE usrno=10;
EXEC SQL WHENEVER SQLERROR GOTO stop_st;
printf("\n 추가된 회원 [%d]번의 거주지역 =[%s]", usrno, usrarea.arr);
EXEC SQL COMMIT WORK;
stop_st;
EXEC SQL ROLLBACK WORK;
printf("\n 오라클 에러=%d",sqlca.sqlerrm.sqlerrmc);
-----------------------------------------------------------------------------
ex1은 insert문장에 함께 기술해 줄 호스트 변수들을 선언해 주었지만...
ex2에서는 선언하지 않았다.
ex2의 첨에 있는 usrarea는 그 다음에 수행할 select명령에 필요한 선언 문장이다.
-----------------------------------------------------------------------------
ex2)
EXEC SQL BEGIN DECLEARE SECTION;
varchar usrarea[10];
int usrno;
EXEC SQL END DECLARE SECTION;
char SqlCmd[100];
int tot;
tot=0;
memset(SqlCmd,0x00,sizeof(SqlCmd));
sprintf(SqlCmd,"insert into forumlist(usrno, usrname, usrarea, \
usrkindcode) values(%d, %s, %s, %s)", \
10,"lee-k-y","seoul","1004");
EXEC SQL EXECUTE IMMEDIATE :SqlCmd;
EXEC SQL WHENEVER SQLERROR GOTO stop_st;
printf("\n Insert Success!");
EXEC SQL SELECT count(*)
into :tot;
from forumlist
EXEC SQL WHENEVER SQLERROR GOTO stop_st;
printf("\n forumlist 테이블에 존재하는 총 회원 수 = %d",tot);
EXEC SQL COMMIT WORK;
EXEC SQL SELECT usrno, usrarea
into :usrno, :usrarea
from forumlist
where usrno=10;
EXEC SQL WHENEVER SQLERROR GOTO stop_st;
printf("\ 추가된 회원 [%d]번의 거주지역 =[%s]",usrarea.arr);
EXEC SQL COMMIT WORK;
stop_st:
EXEC SQL ROLLBACK WORK;
printf("\n 오라클 에러 = %d", sqlca.sqlerrm,sqlerrmc);
-----------------------------------------------------------------------------
-. Proc내에서의 delete문장.
-----------------------------------------------------------------------------
ex1)
EXEC SQL BEGIGN DECLRAE SECTION;
varchar usrarea[10];
int usrno;
EXEC SQL END DECLARE SECTION;
int tot;
tot=0;
EXEC SQL DELETE FORUMLIST WHERE USRNO=10;
EXEC SQL WHENEVER SQLERROR GOTO stop_st;
EXEC SQL COMMIT WORK;
printf("\n Delete 문장 성공!!");
EXEC SQL SELECT count(*)
into :tot;
from forumlist
EXEC SQL WHENEVER SQLERROR GOTO stop_st;
printf("\n forumlist 테이블에 존재하는 총 회원 수 =%d",tot);
EXEC SQL COMMIT WORK;
stop_st:
EXEC SQL ROLLBACK WORK;
printf("\n Oracle Error =%d",sqlca.sqlerrm.sqlerrmc);
-----------------------------------------------------------------------------
-. 어떠한 호스트 변수도 사용하지 않음.
-----------------------------------------------------------------------------
ex2)
EXEC SQL BEGIN DECLARE SECTION;
varchar usrarea[10];
int usrno;
EXEC SQL END DECLARE SECTION;
char SqlCmd[100];
int tot;
tot=0;
memset(SqlCmd,0x00,sizeof(SqlCmd));
sprintf(SqlCmd,"Delete forumlist where usrno=%d",10);
EXEC SQL EXCUTE IMMEDIATE :SqlCmd;
EXEC SQL WHENEVER SQLERROR GOTO stop_st;
EXEC SQL COMMIT WORK;
prinf("\n Delete Success!!");
EXEC SQL SELECT COUNT(*)
INTO :TOT;
FROM FORUMLIST
EXEC SQL WHENEVER SQLERROR GOTO stop_st;
printf("\n forumlist 테이블에 존재하는 총 회원 수=%d",tot);
EXEC SQL COMMIT WORK;
stop_st;
EXEC SQL ROLLBACK WORK;
printf("\n Oracle Error : =%d",sqlca.sqlerrm.sqlerrmc);
-----------------------------------------------------------------------------
-. where절에서 회원의 고유번호값을 지정해주었다.는 점이 ex1과 다른점이다.
-. delete 부분을 다음과 같이 수정해도 된다.
usrnum=10;
sqlprintf(SqlCmd,"delete forumlist where usrno=%d",usrnum);
이처럼 변수를 먼저 선언해준 후 값을 대입해서 삭제 하는 방법도 있다.
-. 트랜잭션의 제어
-. EXEC SQL COMMIT WORK;
: DML 명령인 INSERT, DELETE ,UPDATE 문장을 수행한 경우에 유용하다.
: DDL 명령은 자동 COMMIT 되므로 사용안해도 됨.
-. EXEC SQL ROLLBACK WORK;
############## 또 다른 강좌 ######################
SQL은 인터페이스와 구성요소로 나누어진다.
인터페이스는 대화형 SQL(SQL*Plus)과 내장형 SQL(C, C++)로 나누어진다.
구성요소는 DDL(정의어), DML(조작어), DCL(제어어)로 나누어진다.
내장형 SQL를 사용하는 이유
대화식 SQL은 호스트언어(C, C++)가 갖고 있는 조건문, 반복문, 입출력 등과 같은 기능을 가지고 있지 않아서 일괄처리시나
동일한 업무 반복시에는 사용이 부적합하다. 이때는 내장형 SQL를 사용하면 된다.
※ 오라클에서 제공하는 예비 컴파일러인 Pro*C는 내장형 SQL문이 포함된 소스파일을 C소스로 컴파일해고 이때 컴파일되는
소스의 확장자는 pc(Pro*C)이다.
※ DB2도 오라클과 같은 예비 컴파일러를 제공하는데 보통 DB2 Pro*C라고 부른다.
※ 내장형SQL에서 사용하는 SQL문법은 PL/SQL과 비슷하다.
내장형SQL 용어
단일행 선택연산
질의가 하나의 튜플(레코드)만 생성
커서(Cursor)
1. 커서는 결과 릴레이션의 모든 튜플들을 튜플단위로 가리킨다. 각 튜플은 차례대로 호스트 변수로
인출(FETCH)되어 호스트 언어 프로그램에 의해 처리될수 있다.
2. 내장형 SQL문의 실행결과로 반환된 복수개의 튜플들을 접근할수 있도록 도와주는 개념
3. 질의 실행 결과로 반환된 테이블의 튜플들을 순서대로 가리키는 튜플에 대한 포인터로 생각하면 됨
4. 커서를 이용해서 질의 결과로 반환된 튜플들을 한번에 하나씩 차례로 처리 가능하다.
DECLARE
커서를 정의하는등 커서에 관련된 선언을 하는 명령어
OPEN
커서가 질의 결과의 첫번째 튜플을 가리키도록 설정하는 명령어
FETCH
질의 결과에 대한 다중 튜플을 가지고 있는 커서에서 현재의 다음 튜플로 이동시키는 명령어
CLOSE
질의 실행 결과에 대한 처리 종료시 커서를 닫기위해 사용하는 명령어(커서 종료 명령)
간단한 내장형 SQL사용예제
//# 호스트변수 선언
EXEC SQL BEGIN DECLARE SECTION
int SNO;
char SNAME[20];
char DEPT[6];
char SQLSTATE[5];
EXEC SQL END DECLARE SECTION
//# 호스트변수에 대입
SNO = 100;
//# 쿼리실행 및 단일로우조회
EXEC SQL SELECT SNAME, DEPT
INTO :SNAME, :DEPT
FROM STUDENT
WHERE SNO = :SNO;
※ SQLSTATE가 '00000' 이면 정상실행, '02000' 이면 튜플이 없음
※ 내장형 SQL이 실행후 SQLSTATE 묵시적 변수에 성공, 실패, 오류에 관련된 코드값이 문자형 정수값으로 대입된다.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Pro*C 커서 사용예제
//# 호스트변수 선언
EXEC SQL BEGIN DECLARE SECTION
int dept;
int salary;
EXEC SQL END DECLARE SECTION
//# 호스트변수 대입
dept = 100;
//# 커서 생성 및 쿼리 대입
EXEC SQL DECLARE Person CURSOR FOR
SELECT SALARY
FROM EMP
WHERE DEPT = :dept;
//# 커서 오픈 및 쿼리 실행
EXEC SQL OPEN PERSON;
//# 커서에서 상단부터 1개의 로우 가져옴
EXEC SQL FETCH PERSON INTO :salary;
//# 무한 반복문 실행
while( SQLCODE == 0 )
{
//# Person 커서에서 FETCH한 로우를 UPDATE 처리함
EXEC SQL UPDATE EMP
SET SALARY = SALARY * 1.1
WHERE CURRENT OF PERSON;
//# Person 커서에서 1개의 로우 가져옴
EXEC SQL FETCH Person INTO :salary;
}
//# Person 커서 닫기
EXEC SQL CLOSE PERSON;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
고객 요구사항
직원 원장(직원번호, 주민등록번호, 입사년도, 이름, 부서명, 연봉, 전화번호)에서 직원의 재직년도가 5년, 10년, 15년 이상일경우
각각 연봉의 5%, 10%, 15%를 인상한다.
※ 올해는 2005년
SalaryIncrease()
{
//# 호스트변수 선언
EXEC SQL BEGIN DECLARE SECTION
char SQLSTATE[6];
EXEC SQL END DECLARE SECTION
//# 커서 생성및 쿼리 대입
EXEC SQL DECLARE employeeCur CURSOR FOR
SELECT * FROM 직원;
//# 커서 오픈및 쿼리 실행
EXEC SQL OPEN employeeCur;
while(1)
{
//# 커서에서 한개의 로우 가져옴
EXEC SQL FETCH FROM employeeCur;
//# 에러 발생시 반복문 탈출
if(!strcmp(SQLSTATE, "02000")) break;
//# 재직년도가 15년이상이면 연봉의 15%를 인상
if(2005-입사년도 >= 15)
EXEC SQL UPDATE 직원
SET 연봉=연봉+(연봉*0.15)
WHERE CURRENT OF employeeCur;
//# 재직년도가 10년이상이면 연봉의 10%를 인상
else if(2005-입사년도 >= 10)
EXEC SQL UPDATE 직원
SET 연봉=연봉+(연봉*0.1)
WHERE CURRENT OF employeeCur;
//# 재직년도가 5년이상이면 연봉의 5%를 인상
elseif(2005-입사년도 >= 5)
EXEC SQL UPDATE 직원
SET 연봉=연봉+(연봉*0.05)
WHERE CURRENT OF employeeCur;
}
//# 커서 닫기(DB연결 종료는 안함
EXEC SQL CLOSE employeeCur;
}
상단 Pro*C 설명
내장 SQL에서 변수는 BEGIN DELACRE SECTION과 END DECLARE SECTION 내부에서 선언한다.
그리고 DECLARE 명령어를 이용하여 직원 테이블 전체를 가리키는 커서 employeeCur를 생성한다.
내장SQL에서는 커서를 사용하기 위해서는 OPEN 명령어를 이용하여 커서가 가리키는 직원 테이블의 첫번째 튜플을 가리키도록
설정한다.
커서에서는 다음 튜플을 가져오기 위해 FETCH 명령어를 이용한다.
직원의 연봉을 인상하기 위해 DML문에서 갱신을 위한 UPDATE문을 사용한다.
이때 커서를 이용하기 위한 키워드 CURRENT OF를 이용한다.
마지막으로 CLOSE 명령어를 이용하여 커서를 종료한다.
[출처] https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=human_kim&logNo=9152186
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
댓글 0
| 번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
|---|---|---|---|---|
| 공지 | 오라클 기본 샘플 데이터베이스 | 졸리운_곰 | 2014.01.02 | 86338 |
| 공지 | [SQL컨셉] 서적 "SQL컨셉"의 샘플 데이타 베이스 SAMPLE DATABASE of ORACLE | 가을의 곰을... | 2013.02.10 | 78798 |
| 공지 | [G_SQL] Sample Database | 가을의 곰을... | 2012.05.20 | 95543 |
| 6 |
품질경영기사 자료와 정보 (응시자격, 출제기준, 시험과목, 시험방법, 합격기준, 합격률 등)
| 졸리운_곰 | 2018.02.05 | 2629 |
| 5 |
품질경영기사 독학 난이도
| 졸리운_곰 | 2018.02.05 | 3424 |
| 4 |
품질경영기사_공식요약(필기, 실기)_요점 및 핵심정리
| 졸리운_곰 | 2018.02.05 | 4355 |
| 3 |
품질경영기사 요점정리
| 졸리운_곰 | 2018.02.04 | 3051 |
| 2 |
[품질경영산업기사]직접 시험 본 후기 및 조언입니다
| 졸리운_곰 | 2018.02.03 | 2573 |
| 1 |
<품질경영기사 독학하시는 분들을 위한 공부방법 TIP!>
| 졸리운_곰 | 2018.02.03 | 3068 |

