본문 바로가기

C-Language/Pro C, SQLCA

Pro C, SQLCA

Pro C에서 SQLCA는 구조체이고 SQL Communication Area의 의미

SQLCA구조체의 멤버변수들은 SQL문장이 실행될 때마다 가장 최근 문장의 처리 상태(오류, 경고, 상태정보)를 저장한다

SQLCA구조체를 프로그램 내에서 사용하려면 헤더파일을 포함하거나 다음과 같이 선언해야 한다

#include <sqlca.h>
혹은,
EXEC SQL INCLUDE SQLCA;

 

struct sqlca
{
    char sqlcaid[8]; /* "SQLCA" 문자 스트링 */
     long sqlabc; /* slqca구조체의 길이 */
     long sqlcode; /* 에러코드 */
    struct
    {
        unsigned short sqlerrml; /* 에러 메시지 길이 */
        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] : 안쓰임.
                                 sqlwarn[3] : SELECT문에서 필드 개수와 INTO문의 호스트 변수 개수가일치하지 않음
                                 sqlwarn[4] : DELETE 또는 UPDATE문에서where절이 없음.
                                 sqlwarn[5] : reserved
                                 sqlwarn[6] : 안쓰임.
                                 sqlwarn[7] : 안쓰임. */
    char sqlext[8]; /* reserved */
};


sqlcode : 최후에 실행된 SQL문의 상태코드가 저장됨.
값의 의미

0 : 성공
>0 : SQL은 실행되었지만, 열외가 발생한 경우. WHERE절에 만족하는 행이 없는 경우, 또는  SELECT INTO 또는 FETCH문에서 반환된 행이 없는 경우
<0 : Database, System, Network 또는 Application의 Error가 원인으로 SQL이 실행되지 못함. 치명적 Error. 대부분의 경우 Transaction은 Rollback됨.


sqlerrm
: 직전에 실행된 SQL이 Error인 경우 Error Message 가 저장됨
필드의 의미

sqlerrml : sqlerrmc에 저장되어 있는 문자열의 길이
sqlerrmc : sqlcode내에 저장되어 있는 Error Code에 대한 Text Message 가 저장됨. 문자열은 NULL로 종료하지 않으므로 sqlerrml에서 길이를 확인할 필요가 있음
Ex) sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml]='₩0';
      printf("%s", sqlca.sqlerrm.sqlerrmc);


sqlca를 사용하여 오류코드와 오류메시지를 출력하는 예

#include <stdio.h>
#include "sqlca.h"

void error_msg(char *msg);

int main(void) {

 EXEC SQL BEGIN DECLARE SECTION;
     char *connstr = "scott/ojtit@orcl";
     int empno;
     VARCHAR job[20];
     int deptno;
 EXEC SQL END DECLARE SECTION;
 
 empno = 1000;
 
 EXEC SQL CONNECT :connstr;
 
 if(sqlca.sqlcode == 0) {
  printf("오라클 연결 성공\n");
 }else{
  printf("오류 : 오라클 연결 실패\n");
 }
 
 EXEC SQL WHENEVER NOT FOUND DO error_msg("검색된 행이  없습니다");
 
 EXEC SQL
  DELETE FROM
        EMPLOYEES
  WHERE
        empno = :empno;

 EXEC SQL COMMIT WORK;
 
 EXEC SQL
  SELECT
        empno, job, deptno
  INTO
        :empno, :job, :deptno
  FROM
        EMPLOYEES
  WHERE
        empno = :empno;
  
 job.arr[job.len] = '\0';
   
 printf("empno=%d, job=%s, deptno=%d \n", empno, job.arr, deptno);
 
 printf("프로그램 종료\n");
 return 0; 
  
}

void error_msg(char * msg) {
 printf("%s \n", msg);

 sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0';
 printf("오류코드=%d, 오류메시지=%s \n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
 EXEC SQL ROLLBACK WORK;
 return 1;
}