본문 바로가기

Pro*C/강좌

[Pro*C 강좌] 간식 & 식사 뽑기 만들기 - 3

반응형

Pro*C 강좌.

간식 & 식사 뽑기 만들기 - 3

 

1장에서 테이블을 생성하고 헤더 파일과 main 함수를 작성한뒤 2장에선 각각의 기능을 수행해줄 함수를 모두 작성했습니다 !!

이제 3장에서는 여태까지 작성한 코드를 컴파일해서 간단하게 테스트를 진행해보고~

잘 돌아간다면 예외처리를 조금 추가하는 시간을 가질게요 ~ !

 

1. 컴파일 하기.

 

컴파일을 진행하기전 약간의 팁..

윈도우 환경에서 비쥬얼 스튜디오 등의 컴파일러를 사용하면 단축키 혹은 마우스 클릭질 한번이면 컴파일이 진행되지만..

솔라리스나 리눅스 등에서 vi 를 통해 개발을 하게되면...컴파일을 위한 명령어를 계속해서 써야 됩니다..

엄청난 능력자 분들이야 컴파일 한방에 버그 없이 완벽하게 개발을 하겠지만....전 잦은 버그의 발생으로 컴파일을 굉장히 자주 합니다.. 그래서 컴파일을 할때 항상 파일 하나에 컴파일 명령을 써두고 해당 파일에 실행 권한을 줘서 스크립트 처럼 활용을 합니다.

 

( Makefile 을 이용해 make 명령어로 하면 간단하지 않냐고 하실수도 있는데..

프로젝트 등의 개발을 할땐 물론 Makefile 을 이용하니 "make claen; make" 의 간단한 명령으로 컴파일이 가능하지만,

이렇게 간단한 테스트용도 혹은 공부를 위한 프로그램을 컴파일할땐..그냥..명령어를 활용 합니다..Makefile 작성하기가 더 귀찮.. )

 

Pro*C 컴파일 명령어.

 

우리가 여태 작성한 yc_food.pc 파일을 컴파일 하기 위한 컴파일 명령어 입니다.

userid= 부분에는 1장에서 테이블을 생성했을때 사용한 유저명과 패스워드를 입력 하시면 됩니다.

위의 명령어를 자신이 원하는 이름의 파일을 생성해서 입력해 주고 ~ 실행 권한을 주세요 !

chmod +x [파일명]

이렇게 해주면 스크립트처럼 사용이 가능 합니다.

 

이제 실행을 통해 컴파일을 해보세요 !!

 

저는 컴파일을 진행하기 위한 스크립트 파일명을 "yc_mf" 로 했습니다.

yc_mf 를 실행하니 Pro*C의 버전이랑 이것저것 출력이 되면서 컴파일이 완료 됐습니다.

컴파일을 진행하고 ls 명령어를 써보면 확실하게 완료가 됐는지 확인이 가능합니다.

Pro*C 를 통해 .pc 파일을 컴파일 하면 .c 파일을 생성해주기 때문이죠 ~ !

 

 

이렇게~ 위와같이 yc_food.c 파일이 생성된게 보이시죠 ?

이제 ! yc_food.c 파일을 컴파일해서 실행 파일을 만들어 봅시다 !!

 

.c 파일 컴파일 명령어.

 

위에서 Pro*c 를 컴파일 했을때와 마찬가지로 전 yc_mfc 라는 파일을 만들어 명령어를 입력하고 실행권한을 줬습니다.

 

컴파일을 진행하면 에러가 없을경우 아무 문구 없이 "yc_food" 라는 실행파일이 생성 됩니다.

 

2. 실행 테스트 !!

자 우선 테스트를 위해 몇가지 음식을 추가하고 시작합시다 !!

 

원래는 메뉴가 계속해서 출력 되는데 그러면 스샷이 너무 길게 나와서 제가 빼버렸어요 ㅋ_ㅋ 오해 없으시길...

삭제를 위한 음식과 수정을 위한 음식 그리고 뽑기 진행을 위한 몇가지 음식을 추가~

테스트를 위해 적어도 음식, 간식 각각 2개 이상의 데이터를 추가해주세요 !!

 

이제 정상적으로 모두 추가가 됐는지 확인해보기위해 출력을 해봅시다 !!

 

6번 메뉴를 선택해 출력을 하니 제가 입력한 데이터가 정상적으로 나오네요 !!

ㅋ ㅑ 뿌듯.....ㅋㅋ..

이제 뽑기를 진행해 볼까요 !?

한 3~4번 뽑으니..두종류의 간식이 모두 나오네요..정상적으로 랜덤 숫자를 이용해 뽑기가 진행 됩니다 !!

식사도 한번 뽑기 시도 !!

 

식사 역시도 잘 나오네요 !!

그럼 이제 수정 및 삭제를 진행해봅시다~

 

 

수정과 삭제를 진행하고 출력을 해보니 모두 정상적으로 데이터가 변경 된것을 확인 했습니다 ~ !

이렇게 모든 기능을 테스트 했으니 !! 이제 예외처리를 시작해보겠습니다.

아차차! 하지만 그전에 !!!!!

테스트를 할뿐인데 글이 너무 길어질까바 정상적인 루틴만 간단하게 테스트를 했는데,

실제로 자신이 개발한 프로세스를 테스트 하실때 가장 중요한건 !!!

비정상 루틴 테스트 입니다.

잘되는거야 당연한거에요..문제는 항상 비정상적인 부분에서 발생합니다 !!

꼭!! 자기가 개발한 프로세스를 테스트 하고자 한다면 !!

꼼꼼하게 정상/비정상 모두 완벽하게 테스트를 하는 습관을 들이시길 바래요 !!

 

3. 예외처리 추가 !!

 

예외처리 추가를 해야 하는데 2장에서 나온 소스를 잠시 살펴보면

모든 데이터(음식)를 출력할때 while 문 안에서 이미 들어가 있습니다 !

바로 sqlcode 를 활용한 예외 처리 부분 입니다.

sqlcode 에 담겨오는 리턴코드는 꽤 많은걸로 알고 있는데,

아직 저도 모든 리턴 코드에 대해 알고 있지는 않고..딱히 모든걸 알고 있지 않아도 개발이 가능하다보니...전 딱 3가지의 경우만 예외처리를 합니다.

 

 1403  혹은 100과 동일한 경우와 0이 아닐경우 입니다.

 

결과코드 

 내용

 0

  정상

 0 이 아닌경우

  비정상

 100

  쿼리는 정상적으로 수행했지만 출력할 데이터가 없을 때

 1403

  커서안에 더이상 뽑아낼 데이터가 없을 때

 

자 이제 위와 같은 코드를 처리해주는 예외처리 함수를 작성해 적용해보겠습니다.

함수 명은 간단하게 errchk 로 하고, yc_food.h 파일에 int errchk(); 선언 해준뒤 !!

yc_food.pc 파일에 작성을 해줍시다 !!

int errchk()
{
    if(sqlca.sqlcode == 100 || sqlca.sqlcode == 1403)
    {
        printf("\n\n");
        printf("###################################################\n");
        printf("데이터가 존재하지 않습니다.\n");
        printf("DB Err [%d[%s]\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
        printf("###################################################\n");
        return 100;
    }  
    else if(sqlca.sqlcode != 0)
    /* 기타 에러 처리 */
    {   
        printf("\n\n");
        printf("###################################################\n");
        printf("Data Base Error..\n");
        printf("DB Err [%d[%s]\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
        printf("###################################################\n");
        return -1;
    }
    else
        return 1;
}

 

 

이렇게 작성이 완료 됐다면 이제 함수에 적용을 해야겠죠 ?

get_food 함수에 적용을 해봅시다 !!

 

void get_food(char type)
{
    char food_name[20];
    char food_phone[20];
    char insert_date[20];
    char next;
    int cnt=0, ran=0;
    cnt = get_cnt(type);
    ran = get_ran(cnt);

    /* errchk 함수의 결과값을 받아올 변수 선언. */
    int ret = 0;

    if(ran != 0)
    {

        memset(food_name, 0x00, sizeof(food_name));
        memset(food_phone, 0x00, sizeof(food_phone));
        memset(insert_date, 0x00, sizeof(insert_date));

        EXEC SQL DECLARE get_food_cur CURSOR FOR
            select food_name, food_phone, insert_date from
            (select rownum r, food_name, food_phone, insert_date from select_food
             where food_type=:type
             order by food_name)
            where r = :ran;

        EXEC SQL OPEN get_food_cur;

        ret = errchk();

        if(ret == 1)
        /* 정상일 경우. */
        {
            EXEC SQL FETCH get_food_cur INTO :food_name, :food_phone, :insert_date;
            /* 어차피 딱 1개의 데이터만 출력되는 select 이므로 이부분에서는 예외처리가 필요하지 않겠죠 ?*/

            EXEC SQL CLOSE get_food_cur;

            printf("\n\n");
            printf("############################################\n");
            printf("        ***** 뽑은 음식 정보 *****\n");
            printf("음식 : [%s]\n", food_name);
            printf("번호 : [%s]\n", food_phone);
            printf("입력날자 : [%s]\n", insert_date);
            printf("렌덤숫자 : [%3d]\n", ran);
            printf("############################################\n\n");
        }
    }

    else
        printf("음식의 갯수가 0개 입니다. 음식을 추가한뒤 뽑기를 진행해주세요.\n");

    printf("계속하시려면 Enter 키를 눌러주세요.\n");
    scanf("%c", &next);
    fflush(stdin);
}

 

 

자 이렇게 처리를 해주면 커서를 오픈했을때 데이터가 없거나 이상이 있는경우

에러문구를 출력해주게 됩니다.

나머지 기능을 수행하는 다른 함수들에도 에러체크 부분을 추가하고 컴파일한뒤 테스트를 진행해보세요 !!


그럼 이제 3장을 마치도록 하겠습니다.

혹시 궁금하신 사항이 있으면 댓글 남겨주세요 !

 

오늘도 수고하셨습니다.

 

 

다음 4장에서는 원래 마무리 테스트를 진행하고, 소스를 정리 하려고 했는데

테스트는 자기가 직접 하면서 버그를 찾고 하는 작업이다보니, 제가 실수한 부분을 여러분도 똑같이 실수한다는 보장도 없고 해서,

그간 제가 강좌를 올리면서 작성한 소스와 실행파일 및 컴파일에 사용한 파일들을 정리해서 올려드리고 마무리 하겠습니다.

오늘은 급히 처리할 일이 남아있어서 내일쯤에나 올릴수 있을것 같네요.

 

아무튼!! 내일쯤 올려두겠습니다.

 

수고하셨어요 !

 


반응형