文件中.bat错误处理



我有一个.bat文件,它运行两个SQL文件并移动文件。我需要在这个.bat文件中进行一些错误处理。我希望它采用sql中生成的错误并将其传递给AutoSys。 我得到了这个代码:

#!/bin/sh 
. $HOME/.bash_profile
sqlplus -s $AUTOSYS_DB_USER/$AUTOSYS_DB_PASSWD <<!
WHENEVER OSERROR EXIT 999;
WHENEVER SQLERROR EXIT SQL.SQLCODE;
alter session set nls_date_format='DD/MM/YYYY';
execute P_LOST_APPROVALS;
!
exit_code=$?
if [ $exit_code != 0 ]; then
echo "Error calling sqlplus, return code = " $exit_code
exit $exit_code
fi
exit 0

但是,我需要它在.bat文件中运行而不是Linux?

我目前有:

echo exit | sqlplus -s %CONNECT% @Code.sql 
IF %ERRORLEVEL% NEQ 0 (
echo Unsuccessful
goto @ERROR_HANDLING_SQL
)

完整.bat文件:

@echo off
call config.bat
SET CONNECT=%var1%/%var2%@avpr.world
Pushd  Location

Set SCRIPTPATH=Location
Set RESULTPATH=Location

echo exit | sqlplus -s %CONNECT% @Code.sql
IF %ERRORLEVEL% NEQ 0 (
echo Unsuccessful
goto @ERROR_HANDLING_SQL
)

echo exit | sqlplus -s %CONNECT% @createTXT.sql > File%date:~0,2%%date:~3,2%%date:~6,4%.txt
IF %ERRORLEVEL% NEQ 0 (
echo Unsuccessful
goto @ERROR_HANDLING_SQL
)

move "File%date:~0,2%%date:~3,2%%date:~6,4%.txt" %RESULTPATH%

echo exit | sqlplus -s %CONNECT% @dropTable.sql
IF %ERRORLEVEL% NEQ 0 (
echo Unsuccessful
goto @ERROR_HANDLING_SQL
)

: ERROR_HANDLING_SQL
<echo -1>
pause
Exit

批处理中$?的退出代码的等效项是通过变量%ERRORLEVEL%访问的错误级别。在批处理脚本中,存在一种特殊形式的 if 子句,它使用 errorlevel:IF ERRORLEVEL n等效于:">如果错误级别大于或等于 n"。与 bash 一样,值 0 表示执行的上一个命令没有错误(并非总是如此,某些命令没有设置错误级别)。所以你有两个选择:

  1. IF %ERRORLEVEL% NEQ 0这是 bash 脚本中 if 语句的直译。请注意,您必须在用(...)分隔的代码块中使用延迟扩展版本IF !ERRORLEVEL! NEQ 0(请查看此问题以解释原因)
  2. 恕我直言,哪个更合适IF ERRORLEVEL 1(不过取决于您的喜好)。也可以在(...)代码块中工作,但假设命令永远不会设置负错误级别(从未遇到过,但值得一提)

通常,使用set命令设置变量不会更改错误级别,因此您可以选择两个选项之一。但是由于我现在没有Windows机器来测试它,我会安全地使用它并给你第一个选择。测试第二个选项后,我将编辑我的答案。

set exit_code=%ERRORLEVEL%
if %exit_code% NEQ 0 (  
echo Error calling sqlplus, return code = %exit_code%
exit /b %exit_code%
)

最后一些建议:使用exit /b而不是exit.exit也将批量退出命令行

编辑我已经测试了第二个版本,它也可以工作。所以上面的代码可以替换为:

set exit_code=%ERRORLEVEL%
IF ERRORLEVEL 1 (  
echo Error calling sqlplus, return code = %exit_code%
exit /b %exit_code%
)

这篇博客文章很好地解释了为什么应该使用这个版本而不是使用 %ERRORLEVEL% 变量的第一个版本。

在他的评论中@aschipfl善意地提醒我的另一个选择是使用条件执行运算符&&||

  • command1 && command2只有在成功command1才会执行command2
  • 仅当command1失败时,command1 || command2才会执行command2

这两个运算符都使用退出代码(在大多数情况下与错误级别相同,但并非总是如此)来确定命令是失败还是成功。

我还看到您发布了批处理文件。不过,我想指出一点:goto @ERROR_HANDLING_SQL会抛出错误,因为没有标签@ERROR_HANDLING_SQL。不过,脚本末尾存在一个标签ERROR_HANDLING_SQL。如果您尝试跳转到该标签,则应将所有出现的goto @ERROR_HANDLING_SQL替换为goto ERROR_HANDLING_SQL

最新更新