본문 바로가기
IT/PROGRAM

Pro*C 에러 처리 . WHENEVER

by SidePower 2022. 9. 26.

Pro*C에서 에러 처리하는 방법은 3가지입니다.

 

① WHENEVER문을 이용하는 방법 (묵시적 에러처리)

② sqlca를 이용하는 방법 (명시적 에러처리)

③ oraca를 이용하는 방법 (자세한 에러정보)

 

보통 WHENEVER와 sqlca 2가지를 사용하는데 

프로그램 만드는 개발자의 취향에 따라 sqlca 사용하는 경우도 있고

WHENEVER 사용하는 경우도 있는 거 같아요.

 

oraca는 에러 발생시에 더 상세한 에러 내용을 알고 싶을 때 사용하며

추가적인 작업이 필요하고 WHENEVER와 sqlca 두가지로도 에러처리에 충분하고

DB 쿼리문 에러가 몇 가지로 뻔해서 그런지 거의 사용하지 않는거 같아요.

ㅋ 사용하면 더 좋겠죠.

 

묵시적 에러 처리(WHENEVER)는

SQL 오류에 대해 각각 개별적으로 처리하지 않고 모든 오류를 하나로 뭉쳐서 인지합니다.

 

명시적 에러 처리(sqlca)는

SQL 실행할 때마다 오류를 점검해서 오류마다 개별 처리를 할 수 있습니다.

 

묵시적 에러 처리가 모든 에러를 감지하기 때문에

모든 에러를 한가지로만 처리하니깐

다양한 에러에도 딱히 신경 쓸 필요가 없어서 예전에는 많이들 사용했었던 거 같아요.

요즘은 디테일을 강조하다 보니깐 

명시직 에러 처리로 Pro*C 프로그램에서 디테일하게 에러 처리하게끔 많이들 개발하거나 

묵시적과 명시적을 혼합하는 경우가 많은 거 같아요.

 

이번에는 WHENEVER에 대해서만 간단하게 알아볼게요.

 

 WHENEVER

WHENEVER 구문을 이용한 묵시적 에러 처리

EXEC SQL WHENEVER [condition] [action];

condition 상태로 action 조치를 지정하는 형식입니다.

 

 condition

상태 의미
SQLWARNING 경고 발생한 경우
SQLERROR 에러 발생한 경우
NOT FOUND SELECT 또는 FETCH에서 더이상 데이타가 없는 경우

 

 action

조치 의미
CONTINUE WHENEVER 조건을 무력화 시켜 아무 작동도 하지 않고 다음 라인 정상 수행
예) NOT FOUND 처리일때
EXEC SQL NOT FOUND DO BREAK;  → NOT FOUND면 루프를 빠져나간다.
...
EXEC SQL NOT FOUND CONTINUE;
→ 위에 NOT FOUND DO BREAK;가 있지만 무력화 시켜 BREAK하지 않고
    다음 라인 실행합니다. 
DO 함수() 에러 처리 함수를 지정해서 모든 에러 발생시 함수() 수행함.
DO BREAK while 이나 for 루프문이 있을때 break 처리. 루프 빠져 나오기
DO CONTINUE while 이나 for 루프문이 있을때 continue 처리. 다시 루프 시작 라인부터 수행하기
GOTO 라벨 라벨로 순간 이동함.
STOP 프로그램을 종료 exit 하고 트랜젝션을 롤백 rollcack 처리함.

 

 WHENEVER 적용 범위

WHENEVER 구문으로 conditon과 action을 한번 정의했으면

프로그램 끝까지 모든 SQL에 적용되어 condition일때 action을 수행합니다.

단 실행 중에 다른 WHENEVER 구문을 만나게 되면

다른 WHENEVER 구문의 conditon과 action으로 처리됩니다. 당연하겠죠.ㅋ

 

 CONTINUE

위에 CONTINUE 의미를 참고하세요.

 

 

 DO 함수()

EXEC SQL DECLARE cursor1 CURSOR FOR
SELECT val_1,val_2 FROM T_DATA;

// ♥ DO BREAK action으로 지정하여 아래 while문의 FETCH 수행중에 
// ♥ NOT FOUND 상태가 확인되면 자동으로 while문을 빠져나갑니다.
EXEC SQL WHENEVER NOT FOUND DO sql_err_msg("Not Found");
while(1){
	..
	EXEC SQL FETCH cursor1 INTO :h_val1, :h_val2;
	..
}

sql_err_msg(char * errMsg){
	printf("SQL 에러 [%s]\n",errMsg);
    exit(-1);    
}

 

 DO BREAK , DO CONTINUE

EXEC SQL DECLARE cursor1 CURSOR FOR
SELECT val_1,val_2 FROM T_DATA;

# ♥ DO BREAK action으로 지정하여 아래 while문의 FETCH 수행중에 
# ♥ NOT FOUND 상태가 확인되면 자동으로 while문을 빠져나갑니다.
# 또는 DO CONTINUE action으로 while문부터 수행하게 지정할수 있습니다.
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while(1){
	..
	EXEC SQL FETCH cursor1 INTO :h_val1, :h_val2;
	..
}

또는

EXEC SQL WHENEVER NOT FOUND DO CONTINUE;
while(1){
	if(특정 조건){
		break;
	}
	..
	EXEC SQL FETCH cursor1 INTO :h_val1, :h_val2;
	..
}

 

 GOTO 라벨

EXEC SQL DECLARE cursor1 CURSOR FOR
SELECT val_1,val_2 FROM T_DATA;

♥ 라벨로 이동해서 자동으로 while문을 빠져나갑니다.
EXEC SQL WHENEVER NOT FOUND GOTO label_noData;
while(1){
	..
	EXEC SQL FETCH cursor1 INTO :h_val1, :h_val2;
	..
}

label_noData:
	printf("NOT FOUND\n");
	exit(-1);

 

 STOP

♥ 로그인 오류 나면 종료 처리

EXEC SQL WHENEVER SQLERROR STOP;
EXEC SQL CONNECT :user IDENTIFIED BY :passwd;

 

간단하게 샘플 하나씩만 봤는데요.

condition과 action 다양하게 조합해서 사용하시면 됩니다.

 

감사합니다.

반응형

댓글