728x90

한책임..
 
그동안 수고가 많았습니다.  
내가 회사를 떠나면서 마지막으로 부탁하는 것이니 자세히 읽어 봐 주길 바래요..
 
 
DBIO 출력값을 출력변수로 MOVE 하는 소스는 strcpy 를 사용되고 있으나 보통의 경우 문제는 없다.
그러나  date 타입을 string(14) 로 출력시킬 경우에는 문제가 발생됩니다.
개발자가  일일이 to_char(ls_chg_dtm, 'YYYYMMDDHH24MISS')  과 같이 조작하여 출력할 수도 있겠고 dbms 의 date 타입의 출력 포맷을 고칠 수도 있겠으나
농협에서는 절충안 으로 date 타입을 그냥  char(14) 에 담고 그 데이타는 사용하지 않는 것으로 개발해 왔습니다..
 
문제는 출력변수를 move 하는 과정에서 strcpy 를 사용하면서 데이타가 깨져서 나오기 때문에 strncpy 를 사용해 주시길 요청합니다.

     24 static void _out_data_copy(_pdb_sample_edu_acct_ps215_out_t *s, PfmDbiosample_edu_acct_ps215Output *t) {
     25
     26          strcpy( t->cuno, (char*)s->cuno.arr );
     27          strcpy( t->acno, (char*)s->acno.arr );
     28          t->jan_amt = s->jan_amt;
     29          strcpy( t->tr_dt, (char*)s->tr_dt.arr );
     30          strcpy( t->lschg_dtm, (char*)s->lschg_dtm.arr  );
     31          strcpy( t->ls_cmeno, (char*)s->ls_cmeno.arr  );
     32
     33          PFM_DBG(" t->lschg_dtm=[%s], s->lschg_dtm.arr=[%s]", t->lschg_dtm, (char*)s->lschg_dtm.arr );
     34          PFM_DBG(" t->ls_cmeno =[%s], s->ls_cmeno.arr =[%s]", t->ls_cmeno, (char*)s->ls_cmeno.arr );
     35 }
 
  17779  :validation_proc                    :00129] >> PFMTRY [pfmDbioSelect("sample_edu_acct_ps215", &] 입구
  17780  :pfmAnalysisLogging                 :00102] DB EXEC SQL Query Elapse Time : [0 s / 623 ms] - mapid [sample_edu_acct_ps215] : DML [SELECT] - Error No[0] Record Count[1]
  17781 e:_out_data_copy                     :00033]  t->lschg_dtm=[2008-05-17 19:1pfmtcl123], s->lschg_dtm.arr=[2008-05-17 19:1]
  17782 e:_out_data_copy                     :00034]  t->ls_cmeno =[pfmtcl123], s->ls_cmeno.arr =[pfmtcl123]
  17783  :validation_proc                    :00129] << PFMTRY [pfmDbioSelect("sample_edu_acct_ps215", &] 출구 RC [0] TIME [00.005934]
  17784  :validation_proc                    :00135] ================================
  17785  :validation_proc                    :00135] sample_edu_acct_ps215Out
  17786  :validation_proc                    :00135] --------------------------------
  17787  :validation_proc                    :00135] cuno : cuno = [8000000011]
  17788  :validation_proc                    :00135] 계좌번호 : acno = [AC80000000]
  17789  :validation_proc                    :00135] 잔액 : jan_amt = [10]
  17790  :validation_proc                    :00135] 거래일자 : tr_dt = []
  17791  :validation_proc                    :00135] 최종변경자개인번호 : ls_cmeno = [2008-05-17 19:1pfmtcl123]
  17792  :validation_proc                    :00135] 최종변경일시 : lschg_dtm = [ 19:1pfmtcl123]
  17793  :validation_proc                    :00135] ================================
 
     24 static void _out_data_copy(_pdb_sample_edu_acct_ps215_out_t *s, PfmDbiosample_edu_acct_ps215Output *t) {
     25
     26          strncpy( t->cuno, (char*)s->cuno.arr, LEN_SAMPLE_EDU_ACCT_PS215_CUNO_O );
     27          strncpy( t->acno, (char*)s->acno.arr, LEN_SAMPLE_EDU_ACCT_PS215_ACNO_O );
     28          t->jan_amt = s->jan_amt;
     29          strcpy( t->tr_dt, (char*)s->tr_dt.arr, LEN_SAMPLE_EDU_ACCT_PS215_TR_DT_O );
     30          strncpy( t->lschg_dtm, (char*)s->lschg_dtm.arr, LEN_SAMPLE_EDU_ACCT_PS215_LSCHG_DTM_O );
     31          strncpy( t->ls_cmeno, (char*)s->ls_cmeno.arr, LEN_SAMPLE_EDU_ACCT_PS215_LS_CMENO_O );
     32
     33          PFM_DBG(" t->lschg_dtm=[%s], s->lschg_dtm.arr=[%s]", t->lschg_dtm, (char*)s->lschg_dtm.arr );
     34          PFM_DBG(" t->ls_cmeno =[%s], s->ls_cmeno.arr =[%s]", t->ls_cmeno, (char*)s->ls_cmeno.arr );
     35 }
    
    
  21211  :validation_proc                    :00129] >> PFMTRY [pfmDbioSelect("sample_edu_acct_ps215", &] 입구
  21212  :pfmAnalysisLogging                 :00102] DB EXEC SQL Query Elapse Time : [0 s / 661 ms] - mapid [sample_edu_acct_ps215] : DML [SELECT] - Error No[0] Record Count[1]
  21213 e:_out_data_copy                     :00033]  t->lschg_dtm=[2008-05-17 19:], s->lschg_dtm.arr=[2008-05-17 19:1]
  21214 e:_out_data_copy                     :00034]  t->ls_cmeno =[pfmtcl123], s->ls_cmeno.arr =[pfmtcl123]
  21215  :validation_proc                    :00129] << PFMTRY [pfmDbioSelect("sample_edu_acct_ps215", &] 출구 RC [0] TIME [00.003237]
  21216  :validation_proc                    :00135] ================================
  21217  :validation_proc                    :00135] sample_edu_acct_ps215Out
  21218  :validation_proc                    :00135] --------------------------------
  21219  :validation_proc                    :00135] cuno : cuno = [8000000011]
  21220  :validation_proc                    :00135] 계좌번호 : acno = [AC80000000]
  21221  :validation_proc                    :00135] 잔액 : jan_amt = [10]
  21222  :validation_proc                    :00135] 거래일자 : tr_dt = []
  21223  :validation_proc                    :00135] 최종변경일시 : lschg_dtm = [2008-05-17 19:]
  21224  :validation_proc                    :00135] 최종변경자개인번호 : ls_cmeno = [pfmtcl123]
  21225  :validation_proc                    :00135] ================================
 
 
이 때 사용되는 SQL 은 다음과 같으며 여기서  LSCHG_DTM 은 DATE 타입입니다.

     77         EXEC SQL SELECT  /*+ map_id(sample_edu_acct_ps215) */ CUNO
     78                         , ACNO
     79                         , JAN_AMT
     80                         , TR_DT
     81                         , LSCHG_DTM
     82                         , LS_CMENO
     83         INTO :pdb_out
     84         FROM SAMPLE_EDU_ACCT
     85         WHERE cuno = :pdb_in.cuno
     86         ;
 
 
 
     14 struct _pdb_sample_edu_acct_ps215_out_s {
     15     varchar cuno[LEN_SAMPLE_EDU_ACCT_PS215_CUNO_O+1];
     16     varchar acno[LEN_SAMPLE_EDU_ACCT_PS215_ACNO_O+1];
     17     long jan_amt;
     18     varchar tr_dt[LEN_SAMPLE_EDU_ACCT_PS215_TR_DT_O+1];
     19     varchar lschg_dtm[LEN_SAMPLE_EDU_ACCT_PS215_LSCHG_DTM_O+1];
     20     varchar ls_cmeno[LEN_SAMPLE_EDU_ACCT_PS215_LS_CMENO_O+1];
     21 };

출처 : http://pangate.com/51

728x90

여신 김만기 차장님의 요청에 의하여 오전에 오전임과 같이 만들었으니 향후 검토하신 후에 compile shell 뒤에 append 하여 모든 프로그램 컴파일 할 때 warning 을 보여 준다면 어떨까 검토해 주신 후 적용해 주세요.

프로그램명 : inspect_code
적용룰 : PFM_TRYNJ 절 뒤에 SET_ERR 을 안 한 경우를 찾아 줌
사용예 : 소스가 존재하는 디렉토리로 이동해서 inspect_code 를 실행합니다.

nbtap01#/nbsdev/compile/NLDS/src/service>inspect_code NLDS1001I0
"NLDS1001I0.c", line 475: warning #9999: not found SET_ERR after PFM_TRYNJ
"NLDS1001I0.c", line 1541: warning #9999: not found SET_ERR after PFM_TRYNJ
"NLDS1001I0.c", line 1727: warning #9999: not found SET_ERR after PFM_TRYNJ
nbtap01#/nbsdev/compile/NLDS/src/service>
 
더 필요한 체크 룰이 있다면( code inspection 툴이 체크해 내지 못하는 ) 오전임에게 요청해서 반영하면 되겠죠.
(문의) 프레임웍팀 오은경


/*
 * @file            inspect_code.c
 * @brief           코드 점검
 *
 * @dep-header
 *
 * @history
 *    버    전 : 성  명  :  일  자    :  근거  자료    :          변       경        내       용
 *    --------   ------     --------     -----------     -------------------------------------------
 *    VER1.00  : 오은경  :  20080522  :  proframe 구축 :  신규 개발
 *
 */

/* --------------------------------------- include files ---------------------------------------- */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/*--------------------------------- constant, macro definitions --------------------------------- */
#define RC_NRM     0
#define RC_ERR    -1
#define STRSIZE 1024
#define TRUE       1
#define FALSE      0

#define START_TAG  "//DO_NOT_MODIFY_THIS_LINE-----------START_OF_CODE"
#define END_TAG    "//DO_NOT_MODIFY_THIS_LINE-----------END_OF_CODE"


#define PFM_TRY( _Ftn )                                                             \
        do {                                                                        \
            rc = _Ftn;                                                              \
            if( rc != RC_NRM) goto PFM_CATCH;                                       \
        } while (0)

#define PFM_TRYNJ( _Ftn )                                                           \
        do {                                                                        \
            rc = _Ftn;                                                              \
        } while (0)

/* ------------------------------------ function prototypes ------------------------------------- */
/* static long open_file( FILE *fp, char *file_name ); */
static long read_file( FILE *fp, char * );

/* ------------------------------------ function main ------------------------------------------- */
int main(int argc, char *argv[] )
{
    FILE *fp = NULL;
    FILE *ofp;
    long rc = RC_NRM;
    char file_name[100];
    char base_name[100];

    if ( argc != 2 ) {
        printf("\nargument needed!\n\n");
        return RC_ERR;
    }

    strcpy( base_name, argv[1] );
    sprintf(file_name, "%s.c", base_name );
    fp = fopen(file_name, "r");

    if(fp == NULL) {
        /* printf("FILE OPEN FAILED\n");   */
        return RC_ERR;
    }
    /* printf("FILE OPEN SUCCEED\n");   */


    PFM_TRY(read_file( fp, file_name ));


    fclose(fp);


PFM_CATCH :
    return RC_ERR;
}

/* ---------------------------------------- function body ----------------------------------------*/
static long read_file( FILE *fp, char *file_name ) {

    char line[1028];
    char excpt[10280];
    long line_no = 0;
    long excpt_flag = FALSE;
    long start_flag = FALSE;
    long end_flag = FALSE;
    long seterr_flag = FALSE;
    long trynj_no = 0;

    memset(line, 0x00, sizeof(line));
    while( fgets(line, STRSIZE, fp ) != NULL )  {
        line_no++;

        if ( strstr( line, "PFM_TRYNJ" ) > 0 ) {
            /* printf("PFM_TRYNJ founded line_no=[%ld] \n", line_no); */
            excpt_flag  = TRUE;
            trynj_no    = line_no;
            start_flag  = FALSE;
            end_flag    = FALSE;
            seterr_flag = FALSE;
            continue;
        }

        if( excpt_flag == TRUE ) {
            if ( strstr( line, START_TAG ) > 0 ) {
                start_flag  = TRUE;
                continue;
            }
            else if ( strstr( line, END_TAG ) > 0 ) {
                end_flag = TRUE;
            }
            else if ( strstr( line, "SET_ERR" ) > 0 ) {
                seterr_flag = TRUE;
            }

            if ( start_flag == TRUE ) {
                if( seterr_flag == TRUE ) {
                    excpt_flag  = FALSE;
                    continue;
                }
            }
            if ( end_flag == TRUE && start_flag == TRUE ) {
                if( seterr_flag == FALSE ) {
                    printf("\"%s\", line %ld: warning #9999: not found SET_ERR after PFM_TRYNJ\n",file_name, tr
                    start_flag  = FALSE;
                    end_flag    = FALSE;
                    seterr_flag = FALSE;
                    excpt_flag  = FALSE;
                }
            }

        }

        memset(line, 0x00, sizeof(line));

    }

    return RC_NRM;
}

/* --------------------------------------- E N D  O F  F I L E -----------------------------------*/



이 프로그램을 해당 팀에 일괄 돌리겠다면 다음의 shell 을 이용하면 되겠죠..

#!/bin/ksh
#----------------------------------------------------------#
# 작성자 : 오은경  작성일:2008.5.20
#----------------------------------------------------------#

#----------------------------------------------------------#
# 입력 된 아규먼트 개수를 체크한다
#----------------------------------------------------------#
if [ $# -ne  1 ]
then
    echo "\nUsage : $0 team_code(대문자)"
    echo " \n"
    exit
fi


team_code=$1
cd $PRJROOT/compile/$team_code/src/service

pgm_lst=`ls *.c`
for pgm_one in ${pgm_lst};  do
#    echo $pgm_one
    BASE=`echo $pgm_one|cut -d"." -f1-1`
    inspect_code $BASE
done

cd $PRJROOT/compile/$team_code/src/module

pgm_lst=`ls *.c`
for pgm_one in ${pgm_lst};  do
#    echo $pgm_one
    BASE=`echo $pgm_one|cut -d"." -f1-1`
    inspect_code $BASE
done

cd -

출처 : http://pangate.com/50

728x90

1. 입력값 오류

DBIO 를 작성할 때 VIEW의 출력변수 생성 버튼을 눌렀을 때 아래 그림과 같은 오류 메시지가 나오는 경우가 있다.  이것은 스튜디오의 버그라기 보다는 개발자의 프로프레임 스튜디오 사용법의 미숙함에 기인된다. 

ORA-01840 : 입력된 값의 길이가 날짜 형식에 비해 부족합니다.


사용자 삽입 이미지


DBIO 스튜디오의 view 출력변수 생성시에는 개발자의 편의를 위하여 입력값 자동 설정기능이 있는데 이것을 체크해 놓았을 경우 입력변수에 디폴트 값으로 1 을 세팅하여 SQL을 실행한다. VIEW의 출력변수 생성은 작성된 SQL이 문법적으로 오류가 없는지 수행해 보고 정상동작될 경우 출력변수를 생성해 주는 편의 기능이다.  따라서 원래는 입력변수에 값을 일일이 개발자가 넣어서 실행시켜 주어야 하나 개발자의 편의를 위하여 "입력값자동설정" 기능을 제공하고 있는 것이다.

따라서  이 입력값자동설정 체크를 해제하고 출력변수생성 버튼을 클릭하면 다음과 같이 입력값을 직접 넣을 수 있는 팝업이 뜨게 된다.

사용자 삽입 이미지

기본 세팅 값이 1 로 되어 있는데 이것을 포맷에 맞는 적당한 값을 넣으면 정상 실행 될 것이다. SQL 상에서 포맷이 'YYYYMMDD' 이므로 20080404 와 같은 년월일 모양대로 입력하고 실행하면 오류 없이 출력변수 생성을 할 수 있을 것이다.


2. 수행시간


간혹 SQL 튜닝이 제대로 되지 않아 실행시간이 너무 오래 걸리는 경우  timeout 이 나서 출력변수 생성을 하지 못 하는 경우가 있다. 이런 경우 우선적으로 해야 할 것은 해당 SQL 이 빨리 수행될 수 있도록 튜닝을 하는 것이 우선이다.

그러나 개발 형편상 튜닝을 뒤로 미루고 우선 dbio 부터 작성하고자 한다면 다음과 같은 편법을 이용하여 출력변수를 작성할 수 있다.

출력변수가 FTR_DT, MO_ACNO  두개 라고 가정할 때 다음과 같이 정상 수행될 수 있는 임시 SQL 을 작성하고 이것을 실행하여 출력변수를 먼저 작성할 수 있다.

SELECT '1' FTR_DT, '2' MO_ACNO FROM DUAL

사용자 삽입 이미지

출력변수가 생성이 된 후에 원래의 SQL 을 바꿔서 붙여 넣고 저장을 한다.

(문의) 프레임웍팀 이영균 책임

출처 : http://pangate.com/49

+ Recent posts