본문 바로가기

Pro*C

[Pro*C 오라클 DB] Pro*C 오류,에러 진단과 처리

 

 


 

 

에러나 경고를 감지하고 정보를 얻기 위해서는 별도 통신 영역의 정보를 가진 도구가 필요함

 

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 처리 가능
    • 커서 캐시 검사 (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);  // 프로그램 종료
}