프로시져.테이블내의 13개의 필드에 대한 1000줄의 입력데이타를 처리

CREATE TABLE [EXTUREPLUSSTOCKFOREIGNERMASTER] (
[DATACLASS] VARCHAR2(2),
[INFOMARKETCLASS] VARCHAR2(3),
[STOCKCODE] VARCHAR2(12),
[SERIALNO] VARCHAR2(8),
[TRADEDATE] VARCHAR2(8),
[STOCKLIMITRATE] VARCHAR2(5),
[INDIVIDUALLIMITRATE] VARCHAR2(5),
[LISTINGSTOCKSIZE] VARCHAR2(15),
[ORDERPOSSIBILITYVOLUME] VARCHAR2(15),
[LIMITEXHAUSTCLASS] VARCHAR2(1),
[FILLER1] VARCHAR2(5),
[FILLER2] VARCHAR2(5),

[ENDTEXT] VARCHAR2(1)
);

구분자 방식("N:12345"와 "S:Hello World")을 적용하여 숫자와 문자열을 구분하려면, C/C++ 코드에서 구분자(N: 또는 S:)를 활용하여 데이터를 구분하고, Oracle 프로시저에서 이를 처리하도록 할 수 있습니다. 여기서는 두 가지 주요 방법을 설명하겠습니다:

  1. C/C++ 코드에서 데이터 전처리
  2. Oracle 프로시저에서 데이터 처리

1. C/C++ 코드에서 데이터 전처리

C/C++에서는 입력 데이터를 N:과 S:로 구분하여 Oracle 프로시저로 전달할 수 있도록 준비합니다. 이를 위해 inData 배열을 처리하고, 각 값에 대해 N:은 숫자, S:는 문자열로 판단하여 Oracle 프로시저에 전달합니다.

예제: C/C++ 코드에서 구분자 추가

 
#include <stdio.h>
#include <string.h>
#include <ctype.h>

char inData[1000][13][100];

void preprocessData(char rawData[1000][13][100]) {
    // 배열 초기화 및 데이터 전처리
    for (int i = 0; i < 1000; i++) {
        for (int j = 0; j < 13; j++) {
            if (isdigit(rawData[i][j][0])) { // 숫자인 경우
                snprintf(inData[i][j], 100, "N:%s", rawData[i][j]);
            } else { // 문자열인 경우
                snprintf(inData[i][j], 100, "S:%s", rawData[i][j]);
            }
        }
    }
}

// 예시 호출
int main() {
    char rawData[1000][13][100] = {
        {"12345", "Hello", "67890", "World", "1", "2", "3", "4", "5", "6", "7", "8", "9"},
        {"54321", "Test", "98765", "Example", "10", "20", "30", "40", "50", "60", "70", "80", "90"}
        // 기타 데이터 추가...
    };
    
    preprocessData(rawData);
    
    // 'inData' 배열을 Oracle 프로시저로 전달
}



위 코드에서 preprocessData 함수는 rawData 배열을 받아 각 값에 N: 또는 S:를 접두사로 추가하여 inData 배열에 저장합니다. 이렇게 하면 inData 배열은 숫자와 문자열을 구분할 수 있는 형식으로 변환됩니다.


2. Oracle 프로시저에서 데이터 처리

Oracle 프로시저에서는 전달된 데이터를 구분자(N: 또는 S:)에 따라 숫자와 문자열을 구분해서 처리할 수 있습니다. 이때 문자열의 앞 두 문자를 확인하여 숫자와 문자열을 판별하고, 그에 맞는 처리 로직을 수행합니다.

예제: Oracle 프로시저에서 구분자 처리

CREATE OR REPLACE PROCEDURE bulk_insert_proc (
    p_data IN SYS.ODCIVARCHAR2LIST -- 문자열 배열 타입
)
IS
    v_prefix VARCHAR2(2);
    v_value  VARCHAR2(4000);
BEGIN
    FOR i IN 1..p_data.COUNT / 13 LOOP
        FOR j IN 1..13 LOOP
            v_prefix := SUBSTR(p_data((i-1)*13 + j), 1, 2);  -- 앞의 구분자 확인
            v_value := SUBSTR(p_data((i-1)*13 + j), 3);      -- 구분자 이후의 값
            
            IF v_prefix = 'N:' THEN
                -- 숫자 처리: 여기서는 예를 들어 숫자 컬럼에 값을 삽입
                INSERT INTO EXTUREPLUSSTOCKFOREIGNERMASTER (number_column)
                VALUES (TO_NUMBER(v_value));
            ELSIF v_prefix = 'S:' THEN
                -- 문자열 처리: 문자열 컬럼에 값을 삽입
                INSERT INTO EXTUREPLUSSTOCKFOREIGNERMASTER (string_column)
                VALUES (v_value);
            END IF;
        END LOOP;
    END LOOP;
    
    COMMIT;
END;
/

프로시저 설명:

  1. 구분자 확인: SUBSTR 함수로 문자열의 처음 두 글자인 N: 또는 S:를 확인하여, 숫자인지 문자열인지를 구분합니다.
  2. 숫자 처리: N:으로 시작하는 값은 TO_NUMBER를 사용해 숫자로 변환하여 숫자 컬럼에 삽입합니다.
  3. 문자열 처리: S:로 시작하는 값은 그대로 문자열로 처리하여 문자열 컬럼에 삽입합니다.

3. C/C++에서 Oracle 프로시저 호출

C/C++ 코드에서 위와 같이 전처리된 inData 배열을 Oracle 프로시저로 전달할 수 있습니다. 이때 각 레코드는 13개의 값을 가지며, 각 값은 N: 또는 S:로 시작하는 형태로 전달됩니다.

예제: Oracle 프로시저 호출

#include <oci.h>

// OCI 핸들 및 환경 초기화
OCIEnv     *env;
OCIError   *err;
OCISvcCtx  *svc;
OCIStmt    *stmt;
OCIBind    *bind;
OCIArray   *array_data;

void bulkInsert(char inData[1000][13][100]) {
    // 환경 초기화
    OCIEnvCreate(&env, OCI_THREADED | OCI_OBJECT, NULL, NULL, NULL, NULL, 0, NULL);
    OCIHandleAlloc(env, (void **)&err, OCI_HTYPE_ERROR, 0, NULL);
    OCIHandleAlloc(env, (void **)&svc, OCI_HTYPE_SVCCTX, 0, NULL);

    // Oracle 연결
    OCILogon(env, err, &svc, (text *)"username", strlen("username"), (text *)"password", strlen("password"), (text *)"db", strlen("db"));

    // 배열 준비: 1000 레코드, 13 컬럼
    OCIDescriptorAlloc(env, (void **)&array_data, OCI_DTYPE_TABLE, 0, NULL);
    
    // 데이터를 배열에 삽입
    for (int i = 0; i < 1000; i++) {
        for (int j = 0; j < 13; j++) {
            OCIArrayAppend(array_data, (text *)inData[i][j], strlen(inData[i][j]), err);
        }
    }

    // 프로시저 호출 준비
    OCIStmtPrepare(stmt, err, (text *)"BEGIN bulk_insert_proc(:data); END;", strlen("BEGIN bulk_insert_proc(:data); END;"), OCI_NTV_SYNTAX, OCI_DEFAULT);

    // 바인딩
    OCIBindByName(stmt, &bind, err, (text *)":data", strlen(":data"), (void *)array_data, sizeof(array_data), SQLT_TAB, NULL, NULL, NULL, 0, NULL, OCI_DEFAULT);

    // 실행
    OCIStmtExecute(svc, stmt, err, 1, 0, NULL, NULL, OCI_DEFAULT);

    // 종료
    OCILogoff(svc, err);
    OCIHandleFree(stmt, OCI_HTYPE_STMT);
    OCIHandleFree(err, OCI_HTYPE_ERROR);
    OCIHandleFree(svc, OCI_HTYPE_SVCCTX);
    OCIEnvFree(env, OCI_DEFAULT);
}

결론

  • C/C++ 코드에서 데이터를 N:과 S:로 구분하여 Oracle 프로시저에 전달합니다.
  • Oracle 프로시저에서는 SUBSTR을 사용하여 구분자를 확인하고, 숫자와 문자열을 처리합니다.
  • N: 접두사는 숫자 컬럼에 삽입하고, S: 접두사는 문자열 컬럼에 삽입합니다.

+ Recent posts