【问题标题】:How to stop sqlplus command in unix shell script when any sql fails当任何 sql 失败时如何在 unix shell 脚本中停止 sqlplus 命令
【发布时间】:2016-12-04 01:22:47
【问题描述】:

我是 shell 脚本的新手。 我正在为 DBA 自动化编写代码,其中我有 master.sql 文件有 n 个 sql 的声明。这些 sql 被放置在特定的文件夹中。 我有一个脚本,它正在调用这个 master.sql 并立即间接执行这些 sqls 并保存在日志文件中

sqlplus 命令正在一次保存 master.sql 中声明的所有 sql 的输出 我想要的是它必须在第一个 sql 失败时停止执行并返回失败的特定 sql 的错误或要求回滚并询问你是否要继续? 尝试在任何时候使用 sqlplus,, sqlerror ,$?没有任何效果

sqlplus  ${USER}/${PASS}@$SID  @master.sql > /home/deploy/vidya/properties/result/result.log

现在我要做的是......当任何 sql 从一开始就失败并在命令行上提示错误并指定哪个 sql 失败时,我想停止执行 sqls

master.sql

SET ECHO ON

@/home/deploy/vidya/properties/001_dba_demo.sql
@/home/deploy/vidya/properties/003_dba_demo1.sql
@/home/deploy/vidya/properties/002_dba_demo2.sql
@/home/deploy/vidya/properties/004_dba_demo2.sql

EXIT

我的 .sh 脚本正在调用 master.sql 并且它工作正常

#!/bin/bash

echo "Enter schema Name you want to connect: "
read USER
echo "Enter password: "
read -s PASS
#echo "Enter Oracle SID for the environment you want to connect with  : "
#read SID
echo "Enter Environment for the environment you want to connect with  : "
read ENV
echo "Enter Oracle SID for the environment you want to connect with  : "
read SID

 export ORACLE_SID=${SID}

if [ $ENV ==  UAT ]
then
   echo "Connected withh UAT ORACLE HOME:"
export ORACLE_HOME=/u01/app/oracle/product/11.2.0.4/db_1
elif [ $ENV == PROD ]
then
echo "Connected with PROD ORACLE HOME:"
export ORACLE_HOME=/u01/app/oracle/product/11.2.0.4/db_1

else
 echo "Wrong Environment Entered :"

fi
export PATH=$ORACLE_HOME/bin:$PATH

echo "want to execute sql? y/n"
read yn

sqlplus  ${USER}/${PASS}@$SID  @master.sql > /home/deploy/vidya/properties/result/result.log

**

谁能帮忙?**

【问题讨论】:

标签: bash shell unix build-automation devops


【解决方案1】:

一个想法是按顺序启动 sql,然后检查它们是否有错误: 例如

sqlplus  ${USER}/${PASS}@$SID  @dba_demo.sql > /home/deploy/vidya/properties/result/result_dba_demoSQL.log
checker = $(grep "ERROR" result_dba_demoSQL.log) 
if [ test -z $checker ]
   then echo "dba_demo_SQL successfull run"
   else 
       echo "dba_demo_SQL failed"
       exit 0
fi 

exit 0部分,当grep在日志文件中发现错误时退出整个脚本。

【讨论】:

  • 如果你不想在脚本中写太多的if,你可以把整个东西放在一个for中:例如ls -1 /some_location/folder_with_sqls 中的 f;做上面的_if_part_;完毕。您可以使用 f in 'for f in...' 作为启动某些脚本的变量: sqlplus ${USER}/${PASS}@$SID @$f 并将输出保存到某个日志文件: > /home/ deploy/vidya/properties/result/result_$f.log,并修改checker变量$(grep "ERROR" result_$f.log
  • 一个 sql 失败应该被视为一个错误。将错误消息打印到 stderr,并以非零值退出:... else; echo "dba_demo_SQL failed" >&2; exit 1;
  • 同意William,最好使用出口1
  • 我猜 sqlplus 的主要功能是立即执行 sql 并将其保存在日志文件中。它已经在做。我想要的是一个一个地执行每个 sql,如果任何 sql 失败,那么它应该停止执行并在命令行上给出错误
【解决方案2】:

我猜 sqlplus 的主要功能是立即执行 sql 并将其保存在日志文件中。它已经在做。我想要的是一个一个地执行每个 sql,如果任何 sql 失败,那么它应该停止执行并在命令行上给出错误

【讨论】:

    【解决方案3】:

    很抱歉没有使用 cmets。声望不够。 这是我在第一个答案中的解决方案。 不要通过 sqlplus 启动 master.sql,而是一个一个启动较小的 sql,并在每次执行后检查日志文件。 如果 1 号 sql 的日志文件有错误,则 if 子句中的 exit 1 将终止整个脚本。

        #First query 
        #Sqlplus command to run the first query 
        sqlplus  ${USER}/${PASS}@$SID  @dba_demo.sql > /home/deploy/vidya/properties/result/result_dba_demoSQL.log 
        #variable checker is assigned ERROR, if ERROR is found in file (you have to check what errors you can get from oracle)
        checker = $(grep "ERROR" result_dba_demoSQL.log)
        #If clause that checks if variable checker is empty or not, if variable checker is empty, it means that no string "ERROR" was found in log files, thus script continues to run; If variable is not empty (string ERROR was chatched) script terminates. 
        if [ test -z $checker ]
           then echo "dba_demo_SQL successfull run"
           else 
               echo "dba_demo_SQL failed"
               exit 1
        fi 
        # Second Query
        sqlplus  ${USER}/${PASS}@$SID  @dba_demo1.sql > /home/deploy/vidya/properties/result/result_dba_demo1SQL.log
        checker = $(grep "ERROR" result_dba_demo1SQL.log) 
        if [ test -z $checker ]
           then echo "dba_demo1_SQL successfull run"
           else 
               echo "dba_demo1_SQL failed"
               exit 1
        fi 
    

    【讨论】:

    • 这是一个很好的解决方案,但问题是我正在做 dba 自动化并为客户做这件事,所以这是他们的要求。他们向我们发送了 master.sql 文件,其中包含所有 sql 的声明。所以我们必须执行它。 .所以你能帮忙只用这个方法吗?
    【解决方案4】:

    如果您的 master.sql 与您发布的示例相同,即 sql 文件本身的路径列表,您可以这样做:

        # Read the master.sql file, for every line in master.sql file 
        for i in `cat master.sql`; do
        # basename "$i" takes the name of the file from path present in master.sql 
        sql_name = $(basename "$i")
        # use path in the sqlplus command ($i from the for loop) and sqlname for the log file name
        sqlplus  ${USER}/${PASS}@$SID  @$i > /home/deploy/vidya/properties/result/result_$sql_name.log
    checker = $(grep "ERROR" result_$sql_name.log) 
    if [ test -z $checker ]
       then echo "$sql_name successfull run"
       else 
           echo "$sql_name failed"
           exit 1
    fi ; done
    

    【讨论】:

    • 错误:./run-sqlplus2.sh:第 96 行:=:找不到命令退出 grep:.log:没有这样的文件或目录 ./run-sqlplus2.sh:第 99 行:检查器:找不到命令 ./run-sqlplus2.sh:第 100 行:[:测试:预期一元运算符失败
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-16
    • 1970-01-01
    • 2014-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多