#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, как в моем примере ?