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