当任何sql失败时,如何在unix shell脚本中停止sqlplus命令

时间:2016-07-29 10:46:54

标签: bash shell unix build-automation devops

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

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

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

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

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

**

任何人都可以帮忙吗?**

4 个答案:

答案 0 :(得分:0)

一个想法是按顺序启动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 

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

抱歉不使用评论。没有足够的声誉。 这是我在第一个答案中的解决方案。 不是通过sqlplus启动master.sql,而是逐个启动较小的sqls并在每次执行后检查日志文件。 如果sql number 1的日志文件有错误,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 

答案 3 :(得分:0)

如果你的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