■ 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;
}
//정상처리...
...
}
감사합니다.
'IT > PROGRAM' 카테고리의 다른 글
Pro*C . 한줄 단건만 조회하는 select 예제 (0) | 2022.09.29 |
---|---|
Pro*C 컴파일 과정과 Makefile 만들기 (0) | 2022.09.28 |
Pro*C 에러 처리 . WHENEVER (1) | 2022.09.26 |
오라클 Pro*C 데이타베이스 DB 접속과 해제하기 (0) | 2022.09.26 |
Pro*C . 오라클 DB 데이터를 C / C++ 프로그램으로 제어 (0) | 2022.09.25 |
댓글