본문 바로가기
IT/PROGRAM

Pro*C 에러 처리 . SQLCA

by SidePower 2022. 9. 27.

 SQLCA 에러 처리

오라클에는 SQL 수행시 에러가 발생하면 

SQLCA라는 구조체 필드에 매번 오류 상태를 갱신해 줍니다.

 

항상 마지막 SQL 처리에 대한 상태를 기억하고 있고

SQLCA 구조체를 사용하기 위해 Pro*C 프로그램에 sqlca 해더를 포함시켜야 됩니다.

 

#include <sqlca.h>
또는
EXEC SQL INCLUDE SQLCA

 

 sqlca 구조체

struct sqlca
{
	char sqlcaid[8]; /* "SQLCA" 문자 스트링 , SQL 통신 영역 식별자*/
	long sqlabc; /* slqca구조체의 바이트 길이 */
	long sqlcode; /* 에러코드 */
	struct
	{
		unsigned short sqlerrml; /* 에러 메시지 길이 , \n 포함된 길이 */
		char sqlerrmc[70]; /* 에러 메시지 내용 */
	} sqlerrm;
	char sqlerrp[8]; /* reserved , 향후 사용 예약 공간*/
	long sqlerrd[6]; /* sqlerrp[0] : reserved , 향후 사용 예약 공간
			sqlerrp[1] : reserved , 향후 사용 예약 공간
			sqlerrd[2] : 수행된 행의 개수
			sqlerrd[3] : reserver , 향후 사용 예약 공간
			sqlerrd[4] : 오류 발생 위치
			sqlerrd[5] : reserved , 향후 사용 예약 공간*/
	char sqlwarn[8]; /* sqlwarn[0] : 경고 플래그
			sqlwarn[1] : 문자열이 잘린 호스트 변수에 할당된 경우
			sqlwarn[2] : SQL 그룹 함수의 결과에서 NULL 열이 사용되지 않는 경우
			sqlwarn[3] : SELECT문에서 필드 개수와
					INTO문의 호스트 변수 개수가
					일치하지 않을 경우 , 적은 개수 지정
			sqlwarn[4] : 더 이상 사용하지 않음
			sqlwarn[5] : 컴파일 오류인 경우
			sqlwarn[6] : 더 이상 사용하지 않음.
			sqlwarn[7] : 더 이상 사용하지 않음. */
	char sqlext[8]; /* reserved */
};

 

 sqlca.sqlcode

sqlcode는 SQL 수행 결과에 대한 에러코드입니다.

sqlcode 의미
0 Oracle이 오류나 예외를 감지하지 않고 명령문을 정상 실행함.
음수 데이터베이스, 시스템, 네트워크 또는 애플리케이션 오류로 인해
Oracle이 명령문을 실행하지 않았음.
Rollback 처리해야 된다.
양수 Oracle이 명령문을 실행했지만 예외를 감지했음을 의미합니다.
이것은 Oracle이 WHERE 절 검색 조건을 충족하는 행을 찾을 수 없거나
SELECT INTO 또는 FETCH가 행을 반환하지 않을 때 발생함.

 

 자주 발생하는 오라클 에러 . sqlcode 

sqlcode 의미
ORA-00000 정상
ORA-00001 고유 제약 조건( string . string )이 위반 되었습니다.
조치: 고유 제한을 제거하거나 키를 삽입하지 마십시오.
ORA-01400 NULL을 삽입할 수 없습니다.
조치: NOT NULL 필드에 값 삽입하세요.
ORA-01403 데이터를 찾을 수 없습니다.
ORA-00942 table or view does not exist
조치: table or view 유무를 확인해주세요.
ORA-01036 잘못된 변수 이름/번호
조치: 바인드되는 변수가 sql 문에 있는지 확인하십시오.

 

 

 sqlca.sqlerrd[2]

sqlerrd[2]는 SQL문의 수행 결과로 받은 행 수입니다.

select는 조회된 건수

insert ,update, delete 는 수행된 건수

fetch는 누적 건수

 

 sqlca.sqlerrm 구조체

에러 메시지 내용을 가지고 있는 구조체입니다.

sqlca.sqlerrm.sqlerrml 에러 메시지 바이트 길이
문자열 끝을 나타내는 마지막 \n(Null)값을 포함한 길이입니다.
sqlca.sqlerrm.sqlerrmc 에러 메시지 내용입니다.
char sqlerrmc[70]으므로 70byte 까지만 에러 메시지를 볼수 있습니다.

 

#define SQLERR_LEN sqlca.sqlerrm.sqlerrml
#define SQLERR_MSG sqlca.sqlerrm.sqlerrc

....
....
while(1){

	EXEC SQL FETCH cursor1
	INTO :h_val1 , :h_val2;
    
	if(SQLCODE != 0){
		printf("Fetch 에러 , 에러코드 [%d] , 에러메시지 [%s]\n",SQLERR_LEN-1,SQLERR_MSG);
		break;
	}
	//정상처리...
	...
}

* 결과
Fetch 에러 , 에러코드 [1302] , 에러메시지 [ORA-01403: 데이터를 찾을 수 없습니다.]

printf로 에러 메시지를 표시할때

SQLERR_LEN = sqlca.sqlerrm.sqlerrml 에 뒤에 -1을 하는 이유는

SQLERR_MSG = sqlca.sqlerrm.sqlerrmc 에러 메시지가 문자열이기때문에

마지막에 NULL값이 존재하므로 

NULL을 제거해서 에러 메시지를 한줄에 보기 좋게 표현할수 있어서에요.

NULL을 제거하지 않으면 아래 처럼 ] 대괄호가 다음줄로 내려갑니다.

Fetch 에러 , 에러코드 [1302] , 에러메시지 [ORA-01403: 데이터를 찾을 수 없습니다.
]

 

그리고 sqlerrmc는 최대 70byte까지만 에러 메시지를 표시할수 있어서

오라클의 모든 에러 메시지를 다 표현할수 없습니다.^^;;

 

이럴때 대비해서 sqlglm() 이라는 함수도 같이 제공하고 있어요.

sqlglm는 오라클에서 제공하는 모든 에러에 대해 전체 메시지를 가지고 있습니다.

void sqlglm(char *msg_buffer, size_t *buffer_size, size_t *msg_length);

msg_buffer는 에러 메시지 문자열

buffer_size는 msg_buffer의 byte 크기

msg_length는 발생한 에러 메시지 실제 byte 크기

char sqlerr_msg[200] = {0x00,};
size_t sqlerr_size = 200;
size_t sqlerr_len;

while(1){

	EXEC SQL FETCH cursor1
	INTO :h_val1 , :h_val2;
    
	if(SQLCODE != 0){
		sqlglm(sqlerr_msg,&sqlerr_size,&sqlerr_len);
		printf("Fetch 에러 , 에러메시지 [%.*s]\n",sqlerr_len-1,sqlerr_msg);
		break;
	}
	//정상처리...
	...
}

 

 

감사합니다.

반응형

댓글