2010/03/09 14:19 Programming Story
SQLCA과 WHENEVER Statement
SQL Communications Area (SQLCA)에 대하여...
1. SQLCA의 구조 (sqlca.h header file)
struct sqlca
{
/* ub1 */ char sqlcaid[8];
/* b4 */ long sqlabc;
/* b4 */ long sqlcode;
struct
{
/* ub2 */ unsigned short sqlerrml;
/* ub1 */ char sqlerrmc[70];
} sqlerrm;
/* ub1 */ char sqlerrp[8];
/* b4 */ long sqlerrd[6];
/* ub1 */ char sqlwarn[8];
/* ub1 */ char sqlext[8];
};
#ifdef SQLCA_INIT
= {
{’S’, ’Q’, ’L’, ’C’, ’A’, ’ ’, ’ ’, ’ ’},
sizeof(struct sqlca),
0,
{ 0, {0}},
{’N’, ’O’, ’T’, ’ ’, ’S’, ’E’, ’T’, ’ ’},
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0}
}
#endif
;
1) sqlcaid
: SQLCA ID
: "SQLCA"로 초기화됨.
2) sqlcabc
: SQLCA structure의 크기
3) sqlcode
: 가장 마지막에 수행된 SQL 문의 status code
: 0 - 에러, 예외없이 SQL문이 수행된 경우
: >0 - SELECT INTO나 FETCH의 결과가 no rows이거나,
WHERE-clause search condition에 해당하는 row가 없는 경우
: <0 - DB, 시스템, 네트웍, application 문제로 인하여 SQL문이 수행될 수 없는 경우
- 현재 트랜잭션을 Roll Back한다.
4) sqlerrm
: sqlerrml - sqlerrmc에 저장된 텍스트의 길이
: sqlerrmc - sqlcode에 저장된 에러 크드에 해당하는 메시지
5) sqlerrp
: reserved for future use
6) sqlerrd
: sqlerrd[0], sqlerrd[1] - reserved for future use
: sqlerrd[2] - 가장 마지막에 수행된 SQL 문의 처리된 결과로 나온 Row의 개수
: sqlerrd[3] - reserved for future use
: sqlerrd[4] - 가장 마지막에 수행된 SQL 문의 parse error가 발생한 문자의 위치
: sqlerrd[5] - reserved for future use
7) sqlwarn
: sqlwarn[0] - 다른 warning flag가 set될때, Setting됨.
: sqlwarn[1] - host 변수에 truncated column 값이 할당될때 Setting됨.
: sqlwarn[2] - AVG()나 SUM()같은 Group함수의 결과로 NULL column이
사용되지 않았을 경우 Setting됨.
: sqlwarn[3] - SELECT나 FETCH의 INTO 내에서 사용된 host 변수의 개수가
query select list 개수와 같지 않을때 Setting됨.
: sqlwarn[4] - WHERE없이 UPDATE 혹은 DELETE 연산에 의해서 처리 될때 Setting됨.
: sqlwarn[5] - PL/SQL 에러로 인하여 EXEC SQL CREATE {PROCEDURE| FUNCTION |
PACKAGE | PACKAGE BODY}문이 fail될때
: sqlwarn[6] - This flag is no longer in use
: sqlwarn[7] - This flag is no longer in use
8) sqlext
: reserved for future use.
2. SQLCA 내용
1) SQL문이 수행될때 마다 Oracle에 의해서 업데이트되는 오라클 에러 코드, 경고 플레그,
이벤트 정보, rows-processed count, diagnostics 정보를 포함한다.
2) SQLCA는 항상 가장 마지막에 수행된 SQL 연산의 결과를 반영한다.
3) 하나의 Global SQLCA와 몇개의 Local SQLCA를 선언할 수 있으며, 선언된 영역 내에서
유효한 값을 갖는다.
4) SQL*Net을 사용하여 여러 Local / Remote DB에 접속할경우, 모든 DB는 하나의 동일한
SQLCA를 사용하여 SQL연산의 결과를 나타낸다.
3. SQLCA의 사용
1) MODE=ORACLE (컴파일시)
: SQLCA를 선언해야 함.
=> EXEC SQL INCLUDE SQLCA; 혹은 #include <sqlca.h>로 선언함.
2) MODE=ANSI
: SQLCA 선언은 optional함.
: SQLCA 선언이 없는 경우 SQLCODE, SQLSTATE를 반드시 선언해야함.
: SQLCA, SQLCODE 선언 둘다 있는 경우 SQL 연산 결과로 동일한 status code를 포함.
: WHENEVER SQLWARNING는 반드시 SQLCA 선언되어 있어야 함.
sqlglm() 함수
1. 함수정의
void sqlglm(char *message_buffer, size_t *buffer_size, size_t *message_length);
: message_buffer - 에러 메시지를 저장하기 위한 텍스트 버퍼
: buffer_size - message_buffer의 최대 byte 사이즈
: message_length - 에러 메시지 실제 길이
2. 사용 예
EXEC SQL WHENEVER SQLERROR DO sql_error();
...
/* other statements */
...
sql_error()
{
char msg[200];
size_t buf_len, msg_len;
buf_len = sizeof (msg);
sqlglm(msg, &buf_len, &msg_len); /* note use of pointers */
printf("%.*s\n\n", msg_len, msg);
exit(1);
}
3. 특징
1) SQL error가 발생할때만 sqlglm() 함수는 호출됨.
2) sqlglm() 함수가 호출되기 전에 sqlca.sqlcode나 SQLCODE는 non-zero이다.
WHENEVER Statement
1. 특징
1) Automatic condition checking 및 error handling을 위해 WHENEVER를 사용함.
2) WHENEVER문은 Error, warning condition, “not found” condition 일때, 수행되는
action을 명시함.
2. 구문
EXEC SQL WHENEVER <condition> <action>;
1) Conditions
: SQLWARNING, SQLERROR, NOT FOUND
2) Actions
: CONTINUE, DO, DO BREAK / DO CONTINUE, GOTO label_name, STOP
참고자료 : Pro*C/C++™ Precompiler Programmer’s Guide Release 8.0 참고