从存储数千个值的 shell 变量插入 Oracle 表

从存储数千个值的 shell 变量插入 Oracle 表

我正在尝试将记录插入到 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语句插入多行。

相关内容