티스토리 뷰

오라클에서 제공하는  proc 샘플을 이용하여 작성하였다. 프로프레임 3.0 에서는 거래를 할 때 마다 이미지로그 테이블에 거래 전문을 보관한다. 이것을 조회하여 text 파일로 떨어트린다. 그런 후에 이 전문 정보를 이용하여 재거래를 해 볼 수 있다. 재거래를 하기 위해서는 pfmtcl 이라는 명령을 이용한다.

이미지로그파일은 일자별로 나누어져 있기 때문에 일자를 입력값으로 받아야 한다. 프로그램내에서 Dynamic SQL을 이용하기 위하여 Prepared Statement 방식을 이용하였다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
[pfmilogfetch.pc]
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sqlca.h>
 
#define LEN_MSG_HDR_AR_CTNT        320
#define LEN_MSG_DATA_AR_CTNT1      4000
#define LEN_MSG_DATA_AR_CTNT2      4000
 
#define ARRAY_LENGTH               100
#define MAX_USERNAME               31
#define MAX_SERVICENAME            128
 
/* Declare a host structure tag. */
/* ------------------- Declare a host structure ------------------------- */
struct
{
    long   msg_len  [ARRAY_LENGTH];
    char   msg_hdr  [ARRAY_LENGTH][LEN_MSG_HDR_AR_CTNT+1];
    char   msg_ctnt1[ARRAY_LENGTH][LEN_MSG_DATA_AR_CTNT1+1];
    char   msg_ctnt2[ARRAY_LENGTH][LEN_MSG_DATA_AR_CTNT2+1];
} ilog;
 
/* --------------------------- function body ---------------------------- */
void print_usage(char *name)
{
  printf("Download all image log data\n");
  printf("Usage : %s DD\n", name );
}
/* --------------------------- function body ---------------------------- */
void crtrim(char *paddedString)
{
  size_t len = 0;
  int i   = 0;
 
  len = strlen((const char *) paddedString);
 
  for (i = len - 1; i >= 0; i--)
  {
    if (isspace(paddedString[(int) i]))  {
      paddedString[i] = 0;
    }
    else {
      break;
    }
  }
}
 
/* --------------------------- function body ---------------------------- */
void print_rows(n)
    int n;
{
  int i;
 
  for (i = 0; i < n; i++) {
 
     /* 뒤에 스페이스 제거 : 전문내용에 스페이스가 있을 수도 있으니 경우에 따라 trim 함 */
     crtrim(ilog.msg_ctnt2[i]);
     if( strlen(ilog.msg_ctnt2[i]) == 0 ) {
        crtrim(ilog.msg_ctnt1[i]);
     }
 
     printf("%s%s%s\n",ilog.msg_hdr[i], ilog.msg_ctnt1[i], ilog.msg_ctnt2[i]);
  }
 
}
/* --------------------------- function body ---------------------------- */
void sql_error(msg)
    char *msg;
{
    EXEC SQL WHENEVER SQLERROR CONTINUE;
 
    printf("\n%s", msg);
    printf("\n %.70s \n", sqlca.sqlerrm.sqlerrmc);
 
    EXEC SQL ROLLBACK WORK RELEASE;
    exit(EXIT_FAILURE);
}
 
/* --------------------------- function body ---------------------------- */
int main(int argc, char** argv)
{
   int  num_ret;               /* number of rows returned */
   char sqlstr[1000];
 
   memset(sqlstr, 0x00sizeof(sqlstr));
 
   /* Check Input argument */
   if( argc == 1 ) {
      print_usage(argv[0]);
      return 0;
   }
 
   VARCHAR     user[ MAX_USERNAME ];      /* VARCHAR is an Oracle-supplied struct */
   varchar     pass[ MAX_USERNAME ];      /* varchar can be in lower case also. */
   VARCHAR     svc [ MAX_SERVICENAME];
 
   /* Connect to ORACLE. */
   EXEC SQL WHENEVER SQLERROR DO sql_error("Connect error:");
 
   /* Assign the VARCHAR char array components */
   strncpy((char *) user.arr, "scott", MAX_USERNAME);
   strncpy((char *) svc.arr,  "DEVCOREDB",  MAX_SERVICENAME);
   strncpy((char *) pass.arr, "tiger", MAX_USERNAME);
 
   /* Assign the VARCHAR length components */
   user.len =  (unsigned short) strlen((char *) user.arr);
   pass.len =  (unsigned short) strlen((char *) pass.arr);
   svc.len  =  (unsigned short) strlen((char *)  svc.arr);
   /* Connect to Oracle. */
   EXEC SQL CONNECT :user IDENTIFIED BY :pass USING :svc;
 
   /* hide password */
   memset(pass.arr, 0, MAX_USERNAME);
   pass.len = 0;
 
   EXEC SQL WHENEVER SQLERROR DO sql_error("Oracle error:");
 
    /* Declare a cursor for the FETCH. */
    snprintf(sqlstr, sizeof(sqlstr),
      "SELECT msg_len, msg_hdr_ar_ctnt, msg_data_ar_ctnt1, msg_data_ar_ctnt2 FROM dbown.pfm_ilog_%s", argv[1]);
    strcat( sqlstr, " WHERE GLOB_ID LIKE '2017%'" );
    EXEC SQL PREPARE S FROM :sqlstr;
    EXEC SQL DECLARE c1 CURSOR FOR S;
 
/* Declare a cursor for the FETCH. */
/*    EXEC SQL DECLARE c1 CURSOR FOR
        SELECT msg_len, msg_hdr_ar_ctnt, msg_data_ar_ctnt1, msg_data_ar_ctnt2 FROM dbown.pfm_ilog_07;
*/
 
    EXEC SQL OPEN c1;
 
    /* Initialize the number of rows. */
    num_ret = 0;
 
    /* Array fetch loop - ends when NOT FOUND becomes true. */
    EXEC SQL WHENEVER NOT FOUND DO break;
 
    for (;;)
    {
        EXEC SQL FETCH c1 INTO :ilog;
 
        /* Print however many rows were returned. */
        print_rows(sqlca.sqlerrd[2- num_ret);
        num_ret = sqlca.sqlerrd[2];        /* Reset the number. */
    }
 
    /* Print remaining rows from last fetch, if any. */
    if ((sqlca.sqlerrd[2- num_ret) > 0)
        print_rows(sqlca.sqlerrd[2- num_ret);
 
    EXEC SQL CLOSE c1;
 
    /* Disconnect from the database. */
    EXEC SQL COMMIT WORK RELEASE;
    exit(EXIT_SUCCESS);
}
cs

make file 에서는 프로프레임에서 기본 제공하는 make_common 을 이용하였다.  make 하는 방법은 make -f  pfmilogfetch.mk clean all  과 같이 하면 컴파일이 될 것이다. 컴파일이 정상적으로 종료되면  pfmilogfetch.c, pfmilogfetch.o, pfmilogfetch 파일이 생성된다. 여기서 pfmilogfetch 이 실행 파일이다.

104~106 라인에서 user, password, service 정보를 하드코딩하는 것이 마음에 걸린다면 환경변수 $CONNECT_INFO 에 scott/tiger@DEVCOREDB 와 같이 지정해 놓고 다음의 함수를 이용할 수도 있겠다.  이 함수를 호출하고자 할 때는 104~106 라인을 주석으로 막고 대신에 get_connect_info( user.arr, pass.arr, svc.arr ); 와 같이 써주면 될 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/* --------------------------- function body ---------------------------- */
long
get_connect_info(char *usr, char *pas, char *svc)
{
    char    user[256+1];
    char   *env_user;
    char   *ptr;
    char   *cur_ptr;
 
    env_user = getenv("CONNECT_INFO");
    if( env_user == NULL ) {
        printf("Environment $CONNECT_INFO is not set.\n" );
        return RC_ERR;
    }
    strcpy( user, env_user );
 
    ptr = strchr(user, '/');
 
    if ( ptr == NULL ) {
        printf("CONNECT_INFO format error.\n");
        return RC_ERR;
    }
    else {
        *ptr = 0x00;
        strcpy(usr, user);
        ptr++;
        cur_ptr = ptr;
 
        ptr = strchr(ptr, '@');
        if ( ptr == NULL ) {
            printf("$CONNECT_INFO [%s] Error ... [ Check DBSID ] ", env_user );
            return RC_ERR;
        }
        else {
            *ptr = 0x00;
            strcpy(pas, cur_ptr);
            strcpy(svc, ++ptr );
        }
    }
 
    return RC_NRM;
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
[pfmilogfetch.mk]
 
---------------------------------------------------------------------------- #
# Target
---------------------------------------------------------------------------- #
TARGET  = pfmilogfetch
AP_OBJS = $(TARGET).o  
 
---------------------------------------------------------------------------- #
# MY C Compiler Flag
---------------------------------------------------------------------------- #
MY_C_DEFINE     = 
MY_IPATH        = 
MY_CFLAGS       = 
MY_LDPATH       =
MY_LDLIBS       = 
 
---------------------------------------------------------------------------- #
# Static Objects
---------------------------------------------------------------------------- #
OBJS            = $(AP_OBJS)
 
---------------------------------------------------------------------------- #
# CC compile Flag
---------------------------------------------------------------------------- #
include $(PFMTPL)/mkfiles/make_common
#include $(PFMTPL)/mkfiles/make_dependency_batch
 
---------------------------------------------------------------------------- #
# LD Link Flag
---------------------------------------------------------------------------- #
LD              = cc
LD_PATH = $(MY_LDPATH)  $(TP_LDPATH)  $(ORACLE_LDPATH) $(OS_LDPATH)
LD_LIBS = $(MY_LDLIBS)  $(TP_BATLIBS) $(ORACLE_LDLIBS) $(OS_LDLIBS)
LD_FLAGS        = $(OS_CFLAGS)
 
all: $(TARGET)
 
$(TARGET): $(OBJS)
        $(LD) -o $@ $(OBJS) $(LD_FLAGS) $(LD_PATH) $(LD_LIBS)
#       ldd -r ./$(TARGET) | sort | uniq
 
clean:
        rm -f core ./$(TARGET) $(OBJS) 
 
move:
        mv -f ./$(TARGET) ../bin
cs

 컴파일 완료 후 실행방법은 다음과 같다.

1
pfmilogfetch 07
cs

이렇게 할 경우 07일에 발생했던 거래를 모두 다운로드 받게 된다. 데이터 랑이 너무 많을 경우에는 조회 SQL을 편집하여 조회 대상 범위를 줄인다. 결과는 스크린으로 나오는데 파일로 저장하기 위해서는  " > 파일명" 을 뒤어 추가하여 파일로 떨어트릴 수 있다.

댓글
댓글쓰기 폼