에러나 경고를 감지하고 정보를 얻기 위해서는 별도 통신 영역의 정보를 가진 도구가 필요함
Pro*C 에서는 SQL 통신영역(SQLCA)과 오라클 통신영역(ORACA)라는 두 개의 특수한 데이터 구조를 지원한다
SQLCA 는 Pro*C 프로그램에 필수 요소이고 ORACA는 더 많은 정보를 얻기 위한 선택 요소임
SQLCA를 사용하여 모든 QL 문장의 상태를 감지하고 상태코드의 정보를 줌
더 많은 확장 정보를 얻고자 할 때, 또는 오류가 발생한 시점에 수행된 SQL문의 정보를 확인하기 위해 ORACA를 사용함
Oracle Text File | 요구사항 | 내용 |
sqlca | 필수 | SQLCA 를 위한 선언 |
oraca | 선택 | ORACA 를 위한 선언 |
두 가지 오류 검출
WHENEVER 문장을 사용하여 발생 가능한 모든 오류에 대한 동일한 처리 방식이 수행되도록 할 수 있다.
1. SQLCA
- 모든 Pro*C 프록램에서 프로그램 실행에 관한 정보를 DB와 교환하기 위해선 SQLCA를 필수로 사용함
- SQLCA 는 예외와 오류를 감지하고 출력함
- SQLCA 는 오라클 홈 디렉토리 밑에 precomp/pubilc 에 sqlca.h 로 존재함\
- #include <sqlca.h> 선언하거나
- EXEC SQL INCLUDE SQLCA; 를 통해 선언 (Pro*C 고유문법)
- SQL 문장의 처리 결과에 대해 SQLCA 파일에 정의되어 있는 sqlca 구조체에 정보를 저장
개발자는 구조체 내용을 검색하여 에러와 경고 여부에 대한 정보를 확인 할 수 있다.
struct {
1. char sqlcaid[8]
2. long sqlcabc;
3. long sqlcode;
struct {
4. unsigned short sqlerrml;
5. char sqlerrmc[70];
} sqlerrm;
6. char sqlerrp[8];
7. long sqlerrd[6];
8. char sqlwarn[8];
9. char sqlext[8];
}sqlca;
sqlca 구조체 상세 설명 표
번호배열 인덱스배열명데이터형설명예시 및 용도
번호 | 배열 인덱스 | 배열명 | 데이터형 | 설명 | 예시 및 용도 |
1 | - | sqlcaid | char[8] | SQLCA ID: 이 배열은 SQLCA 구조체를 고유하게 식별하는 ID입니다. 일반적으로 SQLCA와 같은 고정된 값이 설정됩니다. Oracle에서 이 값은 SQLCA를 추적하는 데 사용됩니다. | 예: sqlcaid = "SQLCA"와 같은 고정 값이 설정됩니다. |
2 | - | sqlcabc | long | SQLCA 크기: SQLCA 구조체의 크기를 나타내는 값입니다. Oracle 시스템에서는 이 값을 사용하여 SQLCA 구조체의 크기를 파악하고 이를 전송하는 데 사용됩니다. | 예: sqlcabc = 128는 구조체의 크기가 128바이트임을 나타냅니다. |
3 | - | sqlcode | long | SQL 실행 결과 코드: SQL 문을 실행한 후 반환된 코드입니다. 성공 시 0을, 오류 시 음수나 양수 값이 반환됩니다. 이 값은 SQL 처리 결과를 나타냅니다. | 예: sqlcode = 0은 성공, sqlcode = -1은 오류 발생입니다. |
4 | - | sqlerrml | unsigned short | 오류 메시지 길이: 오류 메시지(sqlerrmc)의 실제 길이를 저장하는 값입니다. 이 값은 sqlerrmc에 저장된 오류 메시지의 길이를 나타냅니다. | 예: sqlerrml = 25이면 오류 메시지 길이가 25자임을 의미합니다. |
5 | - | sqlerrmc | char[70] | 오류 메시지: SQL 실행 중 발생한 오류 메시지를 담고 있는 배열입니다. 최대 70자까지 오류 메시지를 저장할 수 있습니다. | 예: sqlerrmc = "ORA-00001: unique constraint violated"와 같은 오류 메시지 |
6 | - | sqlerrp | char[8] | 오류 발생 위치: 오류가 발생한 프로시저, 함수, 또는 SQL 코드의 위치를 나타내는 문자열입니다. 이 배열은 오류가 발생한 SQL 처리 위치를 식별합니다. | 예: sqlerrp = "MY_PROC"는 오류가 MY_PROC에서 발생했음을 나타냅니다. |
7 | - | sqlerrd | long[6] | 오류 진단 값: 오류와 관련된 진단 정보를 담는 배열입니다. SQLSTATE 코드나 기타 추가적인 오류 진단 정보가 포함됩니다. 오류 발생 시 SQL 처리를 분석하는 데 사용됩니다. | 예: sqlerrd[0] = 100은 특정 오류 코드나 값을 나타냅니다. |
8 | 0 | sqlwarn[0] | char | 경고 메시지: SQL 실행 중 발생한 경고를 추적하는 배열입니다. sqlwarn[0]에는 W가 설정되면, 1개 이상의 널 값이 무시되었음을 경고합니다. | 예: sqlwarn[0] = 'W'는 1개 이상의 널 값이 무시되었음을 나타냅니다. |
9 | 1 | sqlwarn[1] | char | 경고 메시지: sqlwarn[1]에는 W가 설정되면, SQL 문에 중복된 항목이 있음을 경고합니다. | 예: sqlwarn[1] = 'W'는 중복된 항목이 SQL 문에 포함되었음을 경고합니다. |
10 | 2 | sqlwarn[2] | char | 경고 메시지: sqlwarn[2]에는 W가 설정되면, NULL 값이 무시되었거나 다루어지지 않았음을 경고합니다. | 예: sqlwarn[2] = 'W'는 NULL 값이 무시되었음을 나타냅니다. |
11 | 3 | sqlwarn[3] | char | 경고 메시지: sqlwarn[3]에는 W가 설정되면, 인덱스가 없는 컬럼을 조회하거나 경고가 발생한 경우 설정됩니다. | 예: sqlwarn[3] = 'W'는 인덱스가 없는 컬럼을 조회할 때 발생하는 경고입니다. |
12 | 4 | sqlwarn[4] | char | 경고 메시지: sqlwarn[4]에는 W가 설정되면, DISTINCT 키워드가 쿼리에서 사용되었을 때 경고가 발생합니다. | 예: sqlwarn[4] = 'W'는 DISTINCT가 쿼리에서 사용되었을 때 발생하는 경고입니다. |
13 | 5 | sqlwarn[5] | char | 경고 메시지: sqlwarn[5]에는 W가 설정되면, GROUP BY나 ORDER BY의 부정확한 사용을 경고합니다. | 예: sqlwarn[5] = 'W'는 GROUP BY나 ORDER BY에 부정확한 항목이 있을 때 경고입니다. |
14 | 6 | sqlwarn[6] | char | 경고 메시지: sqlwarn[6]에는 W가 설정되면, HAVING 절에 잘못된 연산자가 있을 때 경고합니다. | 예: sqlwarn[6] = 'W'는 HAVING 절에 잘못된 연산자가 있을 때 경고입니다. |
15 | 7 | sqlwarn[7] | char | 경고 메시지: sqlwarn[7]에는 W가 설정되면, ORDER BY 절에서 NULL 값의 정렬 문제가 있을 때 경고가 발생합니다. | 예: sqlwarn[7] = 'W'는 ORDER BY에서 NULL 값이 제대로 정렬되지 않았을 때 경고합니다. |
16 | - | sqlext | char[8] | 확장 오류/경고 정보: SQL 실행 중 발생한 확장된 오류나 경고를 추적하는 배열입니다. 이 값은 확장된 오류나 경고 메시지를 표시하는 데 사용됩니다. | 예: sqlext[0] = 'X'는 확장된 오류 또는 경고가 발생했음을 나타냅니다. |
SQLCA 사용 구문 예시
EXEC SQL UPDATE EMP
SET ENAME = 'MARK';
WHERE EMPNO = '1';
if(sqlca.sqlcode != 0 && sqlca.sqlcode != 1403) {
printf("[에러] 업데이트 SQLCODE : [%d] 메시지 : [%s].\n",
sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
exit(0);
}
EMP 테이블의 데이터를 갱신하면서 발생할 수 있는 오류에 대한 처리
EMPNO가 1 인 데이터에 대해 ENAME 컬럼의 값을 갱신하는 프로그램
SQL 오류가 발생하면 화면에 에러 발생을 알리고 출력
2. ORLCA
- SQLCA 영역에서 얻는 정보보다 더 많은 정보를 사용하고 싶을 경우 사용
- 실행 시 발생하는 에러뿐만 아니라 성능 통계에 대한 보조 정보도 제공
- #include <oraca.h> 선언하거나
- EXEC SQL INCLUDE ORACA; 를 통해 선언 (Pro*C 고유문법)
- 다음 정보를 갖고 있다.
- 현재 SQL 문의 텍스트 (orastxt)
- 에러가 있는 파일의 이름 (orasfrm)
- 에러가 있는 행의 번호 (oraslnr)
- SQL 문 보존 플래그 (orastxtf)
- 이 플래그를 설정 함으로 어느 조건으로 문을 보존할 것인지 선택
- 0. 디폴트 값 SQL 문을 보존하지 않음
- 1. SQLERROR 가 있는 SQL문만을 보존
- 2. SQLERROR 및 SQLWARN 이 이쓴 문을 보존
- 3. SQL 문 전부 보존
- 이 플래그를 설정 함으로 어느 조건으로 문을 보존할 것인지 선택
- DEBUG 처리의 사용 허가 플래그
- 이 플래그는 0이나 1을 설정할 수 있다
- 1을 설정한 경우에는 모든 DEBUG 처리 가능
- 이 플래그는 0이나 1을 설정할 수 있다
- 커서 캐시 검사 (orahchf)
SQLCA는 프로그램 시작 부분에 선언되므로 전역으로 사용 가능하다.
ORACA는 선언만으로는 전역 사용 X
아래 단계를 거쳐야 기능이 활성화 된다
1. EXEC SQL INCLUDE 또는 #include 를 사용하여 ORACA 선언
2. ORACA = YES로 선행 컴파일러 옵션 설정
3. ORACA 에서 필요한 플래그 설정
ORACA 구조체
struct {
1. char oracaid[8];
2. long oracabc;
3. long oracchf;
4. long oradbgf;
5. long orastxtf;
struct {
unsigned short orastxtl;
char orastxtc[70];
} 6. orastxt;
struct {
unsigned short orasfnml;
char orasfnmc[70];
} 7. orasfnm;
8. long oraslnr;
9. long orahoc;
10. long oramoc;
11. long oracoc;
12. long oranor;
13. long oranpr;
14. long oranex;
} oraca;
oraca 구조체 상세 설명 표
이름 | 데이터형 | 설명 | 예시 및 용도 |
oracaid | char[8] | ORACA ID: ORACA 구조체를 고유하게 식별하는 ID입니다. 이 값은 ORACA와 관련된 모든 통신에 대해 고유한 식별자로 사용됩니다. | 예: oracaid = "ORACA"는 ORACA 구조체를 고유하게 식별하는 값입니다. |
oracabc | long | ORACA 크기: ORACA 구조체의 크기를 나타내는 값입니다. 이 값은 해당 구조체의 총 바이트 크기를 저장하여, 이를 통해 데이터 전송 시 구조체의 크기를 파악합니다. | 예: oracabc = 128는 구조체의 크기가 128바이트임을 나타냅니다. |
oracchf | long | ORAC 처리 플래그: ORAC의 처리 상태를 나타내는 플래그입니다. 이 값은 주로 ORAC 처리 흐름의 제어 및 오류 처리를 위해 사용됩니다. | 예: oracchf = 1은 ORAC의 처리가 진행 중임을 나타냅니다. |
oradbgf | long | 디버깅 플래그: 디버깅 모드와 관련된 상태를 저장하는 값입니다. 이 값은 디버깅이 활성화된 경우에 설정되며, 디버깅 정보를 추적하는 데 사용됩니다. | 예: oradbgf = 0은 디버깅이 비활성화된 상태임을 나타냅니다. |
orastxtf | long | 텍스트 플래그: 텍스트 관련 상태를 나타내는 플래그입니다. 이 플래그는 텍스트 데이터를 처리하는 데 관련된 설정을 나타냅니다. | 예: orastxtf = 1은 텍스트 관련 작업이 활성화됨을 나타냅니다. |
orastxtl | unsigned short | 텍스트 길이: orastxtc 배열에 저장된 텍스트의 실제 길이를 나타내는 값입니다. 이 값은 텍스트 배열의 길이를 추적하여 텍스트의 크기를 파악하는 데 사용됩니다. | 예: orastxtl = 25는 orastxtc에 저장된 텍스트의 길이가 25자임을 나타냅니다. |
orastxtc | char[70] | 텍스트 내용: 텍스트 데이터를 저장하는 배열입니다. 이 배열은 최대 70자까지 텍스트를 저장할 수 있으며, 오류 메시지나 기타 텍스트 데이터를 저장하는 데 사용됩니다. | 예: orastxtc = "Error occurred in SQL statement"는 오류 메시지를 저장하는 예입니다. |
orasfnml | unsigned short | 파일명 길이: orasfnmc 배열에 저장된 파일명 문자열의 실제 길이를 나타내는 값입니다. | 예: orasfnml = 10은 orasfnmc에 저장된 파일명의 길이가 10자임을 나타냅니다. |
orasfnmc | char[70] | 파일명: 파일명 문자열을 저장하는 배열입니다. 이 배열은 최대 70자까지 파일명을 저장할 수 있습니다. | 예: orasfnmc = "datafile.sql"는 파일명을 저장하는 예입니다. |
oraslnr | long | 라인 번호: 오류나 경고가 발생한 코드의 라인 번호를 나타내는 값입니다. 이 값은 오류 발생 위치를 추적하는 데 사용됩니다. | 예: oraslnr = 105는 105번째 라인에서 오류가 발생했음을 나타냅니다. |
orahoc | long | 호출 ID: 호출한 프로세스 또는 SQL 문을 식별하는 ID입니다. 이 값은 SQL 문 또는 함수 호출을 추적하는 데 사용됩니다. | 예: orahoc = 1은 호출된 SQL 문 또는 프로시저가 첫 번째로 실행되었음을 나타냅니다. |
oramoc | long | 모듈 ID: SQL 문 또는 프로시저가 실행되는 모듈을 식별하는 ID입니다. 이 값은 SQL 문이 실행되는 모듈을 추적하는 데 사용됩니다. | 예: oramoc = 10은 SQL 문이 10번 모듈에서 실행되었음을 나타냅니다. |
oracoc | long | 커넥션 ID: SQL 문 또는 프로시저가 실행되는 데이터베이스 커넥션을 식별하는 ID입니다. 이 값은 커넥션을 추적하는 데 사용됩니다. | 예: oracoc = 25는 데이터베이스 커넥션이 25번에서 실행되었음을 나타냅니다. |
oranor | long | 옵션 번호: SQL 실행 시 사용된 옵션의 번호를 식별하는 값입니다. 이 값은 SQL 문 실행 시 설정된 옵션을 추적하는 데 사용됩니다. | 예: oranor = 2는 두 번째 옵션이 설정되었음을 나타냅니다. |
oranpr | long | 처리 상태: SQL 문 처리 상태를 나타내는 값입니다. 이 값은 SQL 실행 중의 상태를 추적하는 데 사용됩니다. | 예: oranpr = 3은 세 번째 처리 상태로 SQL이 실행되었음을 나타냅니다. |
oranex | long | 확장 상태: SQL 실행 중 발생한 확장된 상태를 나타내는 값입니다. 이 값은 확장된 오류나 경고 등을 추적하는 데 사용됩니다. | 예: oranex = 100은 확장 상태 코드가 100임을 나타냅니다. |
#include <stdio.h>
#include <sqlca.h>
#include <oraca.h>
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR uid[20];
VARCHAR pwd[20];
EXEC SQL BEGIN DECLARE SECTION;
/* ORACA = YES 는 ORACA를 사용하기 위해 반드시 기술 */
EXEC ORACLE OPTION(oraca = yes);
void main() {
/* 에러 및 경고가 발생한 SQL 문장을 지정하도록 설정 */
oraca.oradbgf = 1; /* 모든 필드 활성화 */
oraca.orastxtf = 3; /* 모든 SQL 문장 보존 */
oraca.oracchf = 1; /* 성능 정보 수집 */
strcpy((char *)uid.arr,"userid");
uid.len = (short) strlen((char*)uid.arr);
strcpy((char *)uid.pwd,"password");
pwd.len = (short) strlen((char*)pwd.arr);
EXEC SQL CONNECT : uid IDENTIFIED BY :pwd;
if(sqlca.sqlcode != 0) {
printf("[에러] Connect Error SQL_MSG : [%d]\n", sqlca.sqlerrm.sqlerrmc);
exit(0);
}
EXEC SQL SELECT empno
INTO : empno
FROM scott.emp
WHERE empno = 1;
if(sqlca.sqlcode < 0) {
printf("\n Error occurred on SQL statement : %.*s", oraca.orastxt.orastxtl, oraca.orastxt.orastxtc);
printf("\n Contained in file : %.*s", oraca.orasfnm.orasfnml, oraca.orasfnm.orasfnmc)
printf("\n Near line number : %d", oraca.oraslnr);
printf("\n ORACLE error number : %d", sqlca.sqlcode);
printf("\n ORACLE error message : %.*s"\n", sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc);
exit();
}
}
}
EXEC SQL CONNECT : uid IDENTIFIED BY :pwd;
if(sqlca.sqlcode != 0) {
printf("[에러] Connect Error SQL_MSG : [%d]\n", sqlca.sqlerrm.sqlerrmc);
exit(0);
}
- EXEC SQL CONNECT: uid와 pwd를 사용하여 Oracle 데이터베이스에 연결을 시도
- 에러 처리: sqlca.sqlcode가 0이 아닌 경우(즉, 에러 발생 시)에는 sqlca.sqlerrm.sqlerrmc를 통해 에러 메시지를 출력
- sqlca.sqlcode: SQL 문을 실행한 후 반환된 상태 코드입니다. 0이면 정상 실행, 0이 아니면 에러가 발생했다는 뜻
- sqlca.sqlerrm.sqlerrmc: 에러 메시지 내용이 저장된 배열입니다. sqlerrmc에 저장된 메시지를 통해 어떤 에러가 발생했는지 알 수 있다
EXEC SQL SELECT empno
INTO : empno
FROM scott.emp
WHERE empno = 1;
if(sqlca.sqlcode < 0) {
printf("\n Error occurred on SQL statement : %.*s", oraca.orastxt.orastxtl, oraca.orastxt.orastxtc);
printf("\n Contained in file : %.*s", oraca.orasfnm.orasfnml, oraca.orasfnm.orasfnmc)
printf("\n Near line number : %d", oraca.oraslnr);
printf("\n ORACLE error number : %d", sqlca.sqlcode);
printf("\n ORACLE error message : %.*s\n", sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc);
exit(0);
}
- SQL 실행: SELECT 쿼리가 실행되고, empno를 scott.emp 테이블에서 조회
- 에러 처리: sqlca.sqlcode가 0보다 작은 값(-1, -2 등)인 경우 에러가 발생했음을 의미.
이 경우 oraca와 sqlca 구조체의 정보를 사용하여 에러의 상세 내용을 출력
에러 상세 정보 출력:
- oraca.orastxt.orastxtl: 에러가 발생한 SQL 문장의 길이
- oraca.orastxt.orastxtc: 에러가 발생한 SQL 문장이 저장된 배열
- oraca.orasfnm.orasfnml: SQL 문장이 포함된 파일 이름의 길이
- oraca.orasfnm.orasfnmc: SQL 문장이 포함된 파일 이름
- oraca.oraslnr: 에러가 발생한 코드 라인 번호
- sqlca.sqlcode: Oracle 데이터베이스에서 반환한 에러 코드
- sqlca.sqlerrm.sqlerrml: 에러 메시지의 길이
- sqlca.sqlerrm.sqlerrmc: 에러 메시지가 저장된 배열
%.*s 설명
**%.*s**는 C 언어에서 printf 함수에서 사용되는 포맷 지정자입니다. 이 구문은 문자열을 출력할 때 유용하며, 특정 길이만큼만 문자열을 출력하고자 할 때 사용됩니다.
- %s: 문자열을 출력할 때 사용되는 포맷 지정자입니다. 예를 들어, printf("%s", "hello");는 "hello"를 출력합니다.
- %.*s: 문자열을 출력할 때, *로 지정된 길이만큼만 출력하는 포맷 지정자입니다. 예를 들어, printf("%.3s", "hello");는 "hel"을 출력합니다. 이때 * 앞에 오는 숫자는 출력할 최대 길이를 나타냅니다.
SQLCA에 비해 설정해야 부분이 많긴 하지만 세부적인 정보를 출력할 수 있다.
오류 검출 및 처리
- 명시적 오류 처리 방식과 묵시적 오류 처리 방식이 있음
- 명시적 오류 처리
- Pro*C 프로그램 안의 SQL 문장 또는 EXEC SQL 문장을 실행 한 후 매번 SQL문장 오류 검사
- 발생 가능한 모든 부분을 명시적으로 기술하여 처리 하는 방식으로 많이 사용된다.
- SQL 문장 밑에 기술하기 때문에 원하는 처리 방식이 가능하다는 장점
- 그만큼 개발자의 주의가 필요함 (깜빡할 수 있음)
- 묵시적 오류 처리
- 전역, 혹은 지역적으로 오류가 발생했을 때의 처리 방안을 기술하여 모든 오류에 동일한 처리
- SQL문장마다 기술하는 것이 아니기 때문에 개발자의 실수는 걱정할 필요 없다.
명시적 오류 처리 | 묵시적 오류 처리 |
정규 호스트 언어 조건 문장 사용 | WHENEVER 문장 사용 |
문장 별로 실행 시간 조건 검사 | 전역적으로 실행 시간 조건 검사 |
논리적으로 SQL 문장에 영향 | 위치적으로 SQL 문장에 영향 |
명시적 오류 처리 예제와 설명
#include <stdio.h> // 표준 입출력 함수 포함
#include <string.h> // 문자열 처리 함수 포함
#include <sqlca.h> // Pro*C에서 제공하는 SQLCA 구조체 포함
#include <stdlib.h> // 표준 라이브러리 함수 포함 (exit 등)
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR username[20]; // 사용자 ID를 저장할 변수
VARCHAR password[20]; // 사용자 비밀번호를 저장할 변수
int empno; // 조회할 직원 번호를 저장할 변수
EXEC SQL END DECLARE SECTION;
void main() {
// 사용자 ID와 비밀번호 설정
strcpy((char *)username.arr, "scott"); // username 배열에 사용자 ID "scott" 저장
username.len = (short)strlen((char *)username.arr); // 사용자 ID의 길이를 설정
strcpy((char *)password.arr, "tiger"); // password 배열에 사용자 비밀번호 "tiger" 저장
password.len = (short)strlen((char *)password.arr); // 비밀번호의 길이를 설정
// Oracle 데이터베이스에 연결 시도
EXEC SQL CONNECT :username IDENTIFIED BY :password;
// SQLCODE 값이 0이 아니면 오류 발생, 오류 처리
if (sqlca.sqlcode != 0) { // sqlcode가 0이 아니면 오류 발생
// 오류 메시지 출력
printf("[에러] Connect Error SQL_MSG : [%s]\n", sqlca.sqlerrm.sqlerrmc);
exit(1); // 오류가 발생하면 프로그램 종료
}
// SELECT 문을 실행하여 scott.emp 테이블에서 empno 값을 조회
EXEC SQL SELECT empno INTO :empno FROM scott.emp WHERE empno = 1;
// SQLCODE 값이 0이 아니면 오류 발생, 오류 처리
if (sqlca.sqlcode != 0) { // sqlcode가 0이 아니면 오류 발생
printf("\n[에러 발생] SQL 문 실행 중 오류 발생\n");
// SQL 문과 에러 메시지 출력
printf("SQL 문: %.*s\n", sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc); // 에러가 발생한 SQL 문 출력
printf("에러 메시지: %.*s\n", sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc); // 에러 메시지 출력
printf("오류 코드: %d\n", sqlca.sqlcode); // 오류 코드 출력
// 추가적으로, `oraca` 구조체에 있는 정보를 통해 보다 상세한 오류 정보를 출력
printf("오류가 발생한 SQL 문: %.*s\n", oraca.orastxt.orastxtl, oraca.orastxt.orastxtc);
printf("오류가 발생한 파일명: %.*s\n", oraca.orasfnm.orasfnml, oraca.orasfnm.orasfnmc);
printf("오류가 발생한 파일 라인 번호: %d\n", oraca.oraslnr);
exit(1); // 오류가 발생하면 프로그램 종료
}
// 정상적으로 실행된 경우, empno 값을 출력
printf("조회된 empno: %d\n", empno);
}
묵시적 오류 처리 전역 설정 예제
#include <stdio.h>
#include <sqlca.h>
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR uid[20];
VARCHAR pwd[20];
EXEC SQL END DECLARE SECTION;
/* 전역 오류 처리 설정 */
EXEC SQL WHENEVER SQLERROR GOTO error_handler; // 전역 설정: 프로그램 내 모든 SQL 문에 적용됩니다.
void main() {
strcpy((char *)uid.arr, "userid");
uid.len = (short)strlen((char*)uid.arr);
strcpy((char *)pwd.arr, "password");
pwd.len = (short)strlen((char*)pwd.arr);
EXEC SQL CONNECT :uid IDENTIFIED BY :pwd;
/* SQL 문에서 오류 발생 시 error_handler로 이동 */
EXEC SQL SELECT empno INTO :empno FROM scott.emp WHERE empno = 1;
printf("SQL 문 실행 후...\n");
return;
error_handler:
/* 오류 처리: sqlca 구조체의 내용을 이용해 에러 코드와 메시지 출력 */
printf("SQL 오류 발생!\n");
printf("SQLCODE: %ld\n", sqlca.sqlcode); // 에러 코드 출력
printf("Error Message: %.*s\n", sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc); // 에러 메시지 출력
exit(1); // 프로그램 종료
}
묵시적 오류 처리 지역 설정 예제
#include <stdio.h>
#include <sqlca.h>
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR uid[20];
VARCHAR pwd[20];
EXEC SQL END DECLARE SECTION;
void main() {
strcpy((char *)uid.arr, "userid");
uid.len = (short)strlen((char*)uid.arr);
strcpy((char *)pwd.arr, "password");
pwd.len = (short)strlen((char*)pwd.arr);
EXEC SQL CONNECT :uid IDENTIFIED BY :pwd;
/* 특정 SQL 문에 대해서만 오류 처리 설정 */
EXEC SQL WHENEVER SQLERROR GOTO error_handler; // 지역 설정: 이 구문은 다음 SQL 문에만 적용됩니다.
/* SQL 문에서 오류 발생 시만 error_handler로 이동 */
EXEC SQL SELECT empno INTO :empno FROM scott.emp WHERE empno = 1;
printf("SQL 문 실행 후...\n");
return;
error_handler:
/* 오류 처리: sqlca 구조체의 내용을 이용해 에러 코드와 메시지 출력 */
printf("SQL 오류 발생!\n");
printf("SQLCODE: %ld\n", sqlca.sqlcode); // 에러 코드 출력
printf("Error Message: %.*s\n", sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc); // 에러 메시지 출력
exit(1); // 프로그램 종료
}
'Pro*C' 카테고리의 다른 글
[Pro*C 오라클 DB] 프로그램 오류 처리, 데이터 처리 (0) | 2025.01.16 |
---|---|
[Pro*C 오라클 DB] 호스트 변수 (배열, 구조체)를 이용한 프로그램 (1) | 2025.01.16 |
[Pro*C 오라클 DB] Pro*C 컴파일 (0) | 2025.01.09 |
[Pro*C 오라클 DB] Pro*C 프로그램 구성과 DB접속 (0) | 2025.01.08 |
[Pro*C 오라클 DB] Pro*C 시작 (2) | 2025.01.06 |