반응형
EXEC SQL WHENEVER를 이용한 오류처리
EXEC SQL WHENEVER ~를 이용한 오류 처리는 Event Handler 방식으로 오류를 처리하는 것으로 <condition>은 Event 종류라고 볼 수 있으며, <action>은 callback이라고 생각하면 됩니다.
EXEC SQL WHENEVER <condition> <action>;
<condition> : Event 종류 상수로 SQLWARNING, SQLERROR, NOT FOUND 등이 있음
<action> : Event에 대한 처리 방법
Condition 종류
SQLWARNING
- Warning이 발생하였을 때에 발생하는 Event로 sqlca.sqlwarn[0]에 값이 설정되며,
sqlca.sqlwarn[1] ~ sqlca.sqlwarn[7] 중에 값이 설정됩니다.
- sqlca.sqlcode에는 양수의 값이 설정되며, +1403은 NOT FOUND에서 처리되므로 제외됩니다.
- SQLWARNING을 사용하기 위해서는 SQLCA에 대해 MODE=ANSI로 설정해야 하며,
sqlca.h를 include해야 합니다.
SQLCA 방식으로 표현하면
if(sqlca.sqlcode > 0 && sqlca.sqlcode != 1403 && sqlca.sqlcode != 100) {
<action>;
}
과 같습니다.
SQLERROR
- sqlca.sqlcode의 값이 음수로 설정되었을 때에 발생합니다.
SQLDA 방식으로 표현하면
if(sqlca.sqlcode < 0) {
<action>;
}
과 같습니다.
NOT FOUND
- sqlca.sqlcode == +1403 이거나 +100(MODE=ANSI로 설정했을 때)에 발생합니다.
- sqlca.sqlcode == +1403인 경우는 SELECT ~ INTO
또는 FETCH ~ INTO 절에서 데이터가 return되지 않는 경우입니다.
- sqlca.sqlcode == +100 (MODE=ANSI로 설정했을 때)인 경우에는
INSERT ~ SELECT문으로 INSERT된 데이터가 없는 경우입니다.
SQLDA 방식으로 표현하면
if(sqlca.sqlcode == 1405 || sqlca.sqlcode == 100) {
<action>
}
과 같습니다.
Action 처리 방법
CONTINUE
- WHENEVER <condition>의 option을 off 시키는 역할을 합니다.
예를들면,
EXEC SQL NOT FOUND DO BREAK;
...
EXEC SQL NOT FOUND CONTINUE;
처럼 위에서 DO BREAK; 설정을 off하여 NOT FOUND 시에 아무 동작을 하지 않도록 합니다.
즉, SQLCA 모드로 변환한다는 의미입니다.
DO handler()
- handler()는 사용자 정의 함수입니다. 즉, 함수는 직접 구현을 해야합니다.
DO BREAK
- while()문 또는 for()문 등의 looping문을 빠져나옵니다.
주로 FETCH시에 NOT FOUND이면 break;하는 용도로 사용합니다.
DO CONTINUE
- while()문 또는 for()문 등의 looping문에서 continue;를 한것과 같습니다.
GOTO lable
- goto lable; 문을 실행합니다.
STOP
- rollback을 수행하고 exit()함수를 호출하여 프로그램을 종료합니다.
오류 처리 방법 (WHENEVER vs. SQLCA)
Sample 1-1). WHENEVER SQLERROR로 오류처리 예
int sql_exceute(void)
{
......
EXEC SQL WHENEVER SQLERROR error_handler("ORACLE ERROR: ");
......
EXEC SQL AT :db_con1 INSERT INTO emp (empno, ename, sal, deptno)
VALUES (:emp_number, :emp_name, :salary, :dept_number);
/* INSERT 오류 발생하면 error_handler() 함수를 자동으로 실행합니다. */
......
}
void error_handler(const char *msg)
{
// CONTINUE를 반드시 해야 함.
// EXEC SQL ROLLBACK WORK; 에서 오류가 발생하면 무한 루프가 됨
EXEC SQL WHENEVER SQLERROR CONINUE;
...
/* 오류 처리 로직 */
...
EXEC SQL ROLLBACK WORK;
}
Sample 1-2). SQLCA로 오류처리한 예
int sql_execute(void)
{
......
EXEC SQL AT :db_con1 INSERT INTO emp (empno, ename, sal, deptno)
VALUES (:emp_number, :emp_name, :salary, :dept_number);
if(sqlca.sqlcode < 0) {
error_handler("ORACLE ERROR: ");
}
....
}
void error_handler(const char *msg)
{
......
/* 오류 처리 로직*/
EXEC SQL ROLLBACK WORK;
}
NOT FOUND 처리 방법 (WHENEVER vs. SQLCA)
Sample 2-1). WHENEVER NOT FOUND처리 예
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while(1) {
EXEC SQL FETCH emp_cursor
INTO :emp_name, :emp_number, :salary;
printf("%s - %ld -%ld\n", emp_name, emp_number, salary);
}
/* FETCH할 데이터가 없으면 자동으로 break문이 실행되어 printf를 실행하지 않음 */
Example 2-2). SQLCA로 NOT FOUND 처리 예
while(1) {
EXEC SQL FETCH emp_cursor
INTO :emp_name, :emp_number, :salary;
if(sqlca.sqlcode == 1403) { // 조건에 맞는 데이터가 없으면...
break;
}
printf("%s - %ld -%ld\n", emp_name, emp_number, salary);
}
See Also : Pro*C 목차 및 Sample Source
반응형
'Oracle > Pro*C' 카테고리의 다른 글
Pro*C 7. Dynamic SQL (0) | 2019.09.25 |
---|---|
Pro*C 6. 대량처리 (배열처리) (0) | 2019.09.25 |
Pro*C 5-1. 오류 처리하기 (SQLCA) (0) | 2019.09.25 |
Pro*C 4. 기본 SQL문 실행 (0) | 2019.09.25 |
Pro*C 3. 변수선언과 INCLUDE (0) | 2019.09.25 |