Как запустить инструкцию insert в oracle DB из сценария оболочки внутри цикла while do

#sql #oracle #shell #do-while

Вопрос:

У меня есть пример использования, когда в моем скрипте оболочки у меня есть цикл выполнения, и мне нужно вставить записи во время этого цикла в базу данных oracle. Поэтому я ожидаю 3 цикла, и каждый раз должна происходить вставка. Но в настоящее время мой код переходит в 1-й цикл, а затем вставляет одну запись и выходит из этого цикла.

 #!/bin/sh  ODATE=${1}  file_deliver_time="20210218:12:56:76" reference_file=/var/tmp/Sneha/SSM_KPI_source_file_checklist.txt HOME_DIR="/var/tmp/Sneha"  source ~/env/INFORMATICA.env source ${HOME_DIR}/db.properties  runScript() { sql ${USER}/"${PASS}"@${DB_INSTANCE} @temp.sql $1 $2 $3 $4  if [[ $? -ne 0 ]]; then echo "Error"; exit 2; fi }  cd ${HOME_DIR}  while read -r line do  echo $line  if [[ -f ${HOME_DIR}/temp.sql ]]; then rm -f ${HOME_DIR}/temp.sql;  fi  echo "whenever sqlerror exit failure;" gt; temp.sql  echo "set define on echo on" gt;gt; temp.sql  echo "INSERT INTO test_ssm_kpi   (source_system,file_name,delivery_timestamp,ODATE) VALUES ('amp;1' ,  'amp;2' , 'amp;3' , 'amp;4');" gt;gt; temp.sql  echo "exit;" gt;gt; temp.sql  file_path=$(echo $line | awk -F ';' '{print $1}' | xargs echo -n )  file_str=$(echo $line | awk -F ';' '{print $2}' | xargs echo -n )  file_type=$(echo $line | awk -F ';' '{print $3}' | xargs echo -n )  file_source_sys=$(echo $line | awk -F ';' '{print $4}' | xargs echo   -n )  echo "runScript ${file_path} ${file_str} ${file_type}   ${file_source_sys}"  runScript ${file_source_sys} ${file_str} ${file_type} ${ODATE} done lt; $reference_file  

Результат, который я получаю сейчас, выглядит следующим образом:

 /var/tmp/Sneha;RTPM_POSITIONS_REPORT_;csv;ARTS runScript /var/tmp/Sneha RTPM_POSITIONS_REPORT_ csv ARTS  SQLcl: Release 18.3 Production on Fri Nov 12 12:01:33 2021  Copyright (c) 1982, 2021, Oracle. All rights reserved.  Last Successful login time: Fri Nov 12 2021 12:01:34  01:00  Connected to: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production Version 19.11.0.0.0  SQLgt; INSERT INTO test_ssm_kpi  (source_system,file_name,delivery_timestamp,ODATE) VALUES ('amp;1' , 'amp;2' ,  'amp;3' , 'amp;4'); old:INSERT INTO test_ssm_kpi  (source_system,file_name,delivery_timestamp,ODATE) VALUES ('amp;1' , 'amp;2' ,  'amp;3' , 'amp;4') new:INSERT INTO test_ssm_kpi  (source_system,file_name,delivery_timestamp,ODATE) VALUES ('ARTS' ,  'RTPM_POSITIONS_REPORT_' , 'csv' , '20211005')  1 row inserted.  SQLgt; exit;  Disconnected from Oracle Database 19c Enterprise Edition Release  19.0.0.0.0 - Production Version 19.11.0.0.0  Note: source_file_checklist.txt this file contains 3 lines of data.   /var/tmp/Sneha;POSITIONS_REPORT_;csv;ARTS  /var/tmp/Sneha;SHORTPOSITION_;xml;SNK  /var/tmp/Sneha;NETPOSITION__;xml;SNT  

Как заставить мой код проходить цикл 3 раза, и в каждом цикле он вставляет запись. Я не понимаю, чего не хватает в моем сценарии оболочки.

Заранее большое спасибо за вашу помощь.

Комментарии:

1. каково содержание справочного файла ? Я думаю, что вам не нужны вторые «ЕСЛИ», вы можете использовать awk их для получения значений каждой строки

Ответ №1:

Еще одна альтернатива, которую легче читать и поддерживать. Это всего лишь пример в моем случае, но просто замените select для вставки, которая находится в вашем случае, и конфигурацию файла свойств.

 $ pwd /home/ftpcpl $ cat reference.txt /home/ftpcpl;POSITIONS_REPORT_;csv;ARTS /home/ftpcpl;SHORTPOSITION_;xml;SNK /home/ftpcpl;NETPOSITION__;xml;SNT  

Теперь мой тестовый сценарий

 #!/bin/sh  ODATE=${1}  file_deliver_time="20210218:12:56:76" reference_file=/home/ftpcpl/reference.txt HOME_DIR="/home/ftpcpl"  runScript() { ${ORACLE_HOME}/bin/sqlplus "/ as sysdba" @temp.sql $1 $2 $3 $4 if [[ $? -ne 0 ]]; then  exit 2; fi  }  cd ${HOME_DIR}  while read -r line do  echo $line  if [[ -f ${HOME_DIR}/temp.sql ]]; then rm -f ${HOME_DIR}/temp.sql; fi  echo "whenever sqlerror exit failure;" gt; temp.sql  echo "set define on echo on" gt;gt; temp.sql  echo "select 'amp;1' , 'amp;2' , 'amp;3' , 'amp;4' from dual;" gt;gt; temp.sql  echo "exit;" gt;gt; temp.sql  file_path=$(echo $line | awk -F ';' '{print $1}' | xargs echo -n )  file_str=$(echo $line | awk -F ';' '{print $2}' | xargs echo -n )  file_type=$(echo $line | awk -F ';' '{print $3}' | xargs echo -n )  file_source_sys=$(echo $line | awk -F ';' '{print $4}' | xargs echo -n )  echo "runScript ${file_path} ${file_str} ${file_type} ${file_source_sys}"  runScript ${file_path} ${file_str} ${file_type} ${file_source_sys} done lt; /home/ftpcpl/reference.txt  

А теперь давайте запустим его

 ./test_loop.sh /home/ftpcpl;POSITIONS_REPORT_;csv;ARTS runScript /home/ftpcpl POSITIONS_REPORT_ csv ARTS  SQL*Plus: Release 19.0.0.0.0 - Production on Tue Nov 9 17:17:52 2021 Version 19.6.0.0.0  Copyright (c) 1982, 2019, Oracle. All rights reserved.   Connected to: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production Version 19.6.0.0.0  SQLgt; select 'amp;1' , 'amp;2' , 'amp;3' , 'amp;4' from dual; old 1: select 'amp;1' , 'amp;2' , 'amp;3' , 'amp;4' from dual new 1: select '/home/ftpcpl' , 'POSITIONS_REPORT_' , 'csv' , 'ARTS' from dual  '/HOME/FTPCP 'POSITIONS_REPORT 'CS 'ART ------------ ----------------- --- ---- /home/ftpcpl POSITIONS_REPORT_ csv ARTS  SQLgt; exit; Disconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production Version 19.6.0.0.0 /home/ftpcpl;SHORTPOSITION_;xml;SNK runScript /home/ftpcpl SHORTPOSITION_ xml SNK  SQL*Plus: Release 19.0.0.0.0 - Production on Tue Nov 9 17:17:54 2021 Version 19.6.0.0.0  Copyright (c) 1982, 2019, Oracle. All rights reserved.   Connected to: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production Version 19.6.0.0.0  SQLgt; select 'amp;1' , 'amp;2' , 'amp;3' , 'amp;4' from dual; old 1: select 'amp;1' , 'amp;2' , 'amp;3' , 'amp;4' from dual new 1: select '/home/ftpcpl' , 'SHORTPOSITION_' , 'xml' , 'SNK' from dual  '/HOME/FTPCP 'SHORTPOSITION 'XM 'SN ------------ -------------- --- --- /home/ftpcpl SHORTPOSITION_ xml SNK  SQLgt; exit; Disconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production Version 19.6.0.0.0 /home/ftpcpl;NETPOSITION__;xml;SNT runScript /home/ftpcpl NETPOSITION__ xml SNT  SQL*Plus: Release 19.0.0.0.0 - Production on Tue Nov 9 17:17:55 2021 Version 19.6.0.0.0  Copyright (c) 1982, 2019, Oracle. All rights reserved.   Connected to: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production Version 19.6.0.0.0  SQLgt; select 'amp;1' , 'amp;2' , 'amp;3' , 'amp;4' from dual; old 1: select 'amp;1' , 'amp;2' , 'amp;3' , 'amp;4' from dual new 1: select '/home/ftpcpl' , 'NETPOSITION__' , 'xml' , 'SNT' from dual  '/HOME/FTPCP 'NETPOSITION_ 'XM 'SN ------------ ------------- --- --- /home/ftpcpl NETPOSITION__ xml SNT  SQLgt; exit; Disconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production Version 19.6.0.0.0  

Комментарии:

1. Привет @Роберт Эрнандес, Если я запущу ваш измененный сценарий, то он все еще не войдет в цикл и не напечатает 3 раза инструкцию insert, присутствующую в temp.sql.

2. Привет @Роберт Эрнандес, также я вижу, что 3 инструкции insert выполняются в базе данных, но все записи одинаковы и для самого 1-го цикла. Это снова показывает нам, что он не вошел во 2-й и 3-й цикл, чтобы извлечь следующие строки из файла и преобразовать значения в новый оператор insert. Не могли бы вы любезно сообщить мне ваши дальнейшие предложения здесь.

3. покажите содержимое файла в своем вопросе

4. это было именно так. Позвольте мне попробовать провести второй тест

5. @Sneha, попробуйте две вещи: Замените done lt; $reference_file на done lt; /var/tmp/Sneha/SSM_KPI_source_file_checklist.txt . Вместо использования интерфейса командной строки разработчика sql, можете ли вы попробовать sqlplus, как в моем примере ?