我正在尝试将记录插入到 Oracle 中的列中,其中值是从 shell 变量传递的。该变量本身存储从文件列表生成的模式。该模式是在 for 循环内的每次迭代时生成的。
每个变量值都插入到 for 循环内的表中。但由于该变量一次只读取一条记录,因此一次只插入一行。有数千个文件正在被读取。
包含在 sqlplus 内运行的命令和 shell 命令的代码作为函数运行。请查找以下代码:
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 中提高此过程的速度?理想情况下,我希望一次性插入所有记录,而在每次迭代中,插入语句仅添加一条记录。
欢迎任何建议。
答案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
语句插入多行。