何千もの値を格納するシェル変数からOracleテーブルに挿入する

何千もの値を格納するシェル変数からOracleテーブルに挿入する

値がシェル変数から渡されるOracleの列にレコードを挿入しようとしています。変数自体はファイルリストから生成されたパターンを保存します。パターンは for ループ内の各反復で生成されます。

各変数値は for ループ内のテーブルに挿入されます。ただし、変数は一度に1つのレコードのみを読み取るため、一度に1行だけ挿入されます。何千ものファイルを読んでいます。

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つのレコードのみを追加します。

どんな提案でも歓迎します。

答え1

insert1つのオプションは、次のようにステートメントリストを作成し、リスト全体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はわかりませんが、insert1つの文で複数の行を挿入する方法があるかもしれません。

関連情報