수천 개의 값을 저장하는 쉘 변수에서 Oracle 테이블에 삽입

수천 개의 값을 저장하는 쉘 변수에서 Oracle 테이블에 삽입

값이 쉘 변수에서 전달되는 Oracle의 열에 레코드를 삽입하려고 합니다. 변수 자체는 파일 목록에서 생성된 패턴을 저장합니다. 패턴은 for 루프 내의 각 반복에서 생성됩니다.

각 변수 값은 for 루프 내부의 테이블에 삽입됩니다. 그러나 변수는 한 번에 하나의 레코드만 읽으므로 한 번에 하나의 행만 삽입됩니다. 수천 개의 파일을 읽고 있습니다.

sqlplus 내에서 실행되는 명령과 셸 명령이 포함된 코드는 함수로 실행됩니다. 다음 코드를 찾아보세요:

function call_HEAD_INSERT
{
    FILES=/home/oracle/LOG_*.DAT
    for f in $FILES
    do
      #echo "Processing $f file..."
      # take action on each file. $f store current file name
      
      ptrn=`grep "HEAD" $f`
      #echo $ptrn
        
       echo "set feedback off;
             set heading off;
             set serveroutput on size unlimited;
    
             VARIABLE GV_return_code    NUMBER;
                     VARIABLE GV_script_error   CHAR(255);
    
             EXEC :GV_return_code := 0;
    
             WHENEVER SQLERROR EXIT 1
    
             DECLARE
               L_error_message VARCHAR2(255);
            BEGIN
                 insert into user.customer(HEAD) values ('$ptrn');
                commit;
            EXCEPTION
               WHEN OTHERS THEN
                  ROLLBACK;
                  :GV_return_code := 1;
                  :GV_script_error := SQLERRM;
            END;
             /
    
             print :GV_script_error;
             exit :GV_return_code;
             /" | sqlplus -s ${ORACLE_LOGIN} >> ${logFile}
            
    done 
    return $?
}

스크립트나 쿼리 속도를 높일 수 있는 방법이 있나요? 쿼리에 병렬 힌트를 제공하려고 시도했지만 실제로 프로세스 속도가 빨라지지는 않았습니다.

그렇다면 스크립트나 PL/SQL에서 이 프로세스의 속도를 높이는 다른 방법이 있습니까? 이상적으로는 모든 레코드를 한 번에 삽입하고 싶습니다. 각 반복마다 insert 문은 하나의 레코드만 추가합니다.

어떤 제안이라도 환영합니다.

답변1

insert한 가지 옵션은 다음과 같이 명령문 목록을 작성 하고 sqlplus전체 목록에 대해 한 번 실행하는 것입니다.

function call_HEAD_INSERT
{
    local files=/home/oracle/LOG_*.DAT
    local insertStatement=""

    # Loop over all files and build a single insertStatement containing the
    # the necessary content from each file
    for f in ${files}; do
        local ptrn="$(grep HEAD "${f}")"
        insertStatement="${insertStatement}
insert into user.customer(HEAD) values ('$ptrn');"
    done

        # Run sqlplus once with all the inserts
        cat <<- EOF | sqlplus -s "${ORACLE_LOGIN}" >> "${logFile}"
set feedback off;
set heading off;
set serveroutput on size unlimited;

VARIABLE GV_return_code    NUMBER;
VARIABLE GV_script_error   CHAR(255);

EXEC :GV_return_code := 0;

WHENEVER SQLERROR EXIT 1

DECLARE
    L_error_message VARCHAR2(255);
BEGIN
    ${insertStatement}
    commit;
EXCEPTION
    WHEN OTHERS THEN
        ROLLBACK;
        :GV_return_code := 1;
        :GV_script_error := SQLERRM;
END;
/

print :GV_script_error;
exit :GV_return_code;
EOF
}

Oracle의 SQL은 모르지만 insert하나의 명령문으로 여러 행을 삽입하는 방법이 있을 수 있습니다.

관련 정보