如何处理调用 sqlplus 的批处理文件中的错误,因为 sqlplus 没有在错误或失败时设置 ERRORLEVEL?
Posted
技术标签:
【中文标题】如何处理调用 sqlplus 的批处理文件中的错误,因为 sqlplus 没有在错误或失败时设置 ERRORLEVEL?【英文标题】:How do I handle errors in a batch file that calls sqlplus, because sqlplus doesn't set ERRRORLEVEL on error or failure? 【发布时间】:2011-12-02 01:20:16 【问题描述】:我在这里遇到了一个问题,我已经花了几天时间来解决它..
我的解释会很长,但我尽量保持简短。
在我的 Oracle SQLdeveloper 中,我有一个包名 UT_BETWNSTR,其中包含:
create or replace
PACKAGE "UT_BETWNSTR"
IS
PROCEDURE ut_setup;
PROCEDURE ut_teardown;
PROCEDURE ut_betwnstr;
END UT_BETWNSTR;
包体是这样的:
create or replace
PACKAGE BODY "UT_BETWNSTR"
IS
PROCEDURE ut_setup IS
BEGIN
NULL;
END;
PROCEDURE ut_teardown
IS
BEGIN
NULL;
END;
PROCEDURE ut_BETWNSTR IS
BEGIN
utAssert.eq (
'Typical valid usage',
BETWNSTR(
STRING_IN => 'abcdefg',
START_IN => 3,
END_IN => 5)
,
'abc'
);
utAssert.isnull (
'NULL start',
BETWNSTR(
STRING_IN => 'abcdefg',
START_IN => NULL,
END_IN => 5)
);
utAssert.isnull (
'NULL end',
BETWNSTR(
STRING_IN => 'abcdefg',
START_IN => 2,
END_IN => NULL)
);
utAssert.isnull (
'End smaller than start',
BETWNSTR(
STRING_IN => 'abcdefg',
START_IN => 5,
END_IN => 2)
);
utAssert.eq (
'End larger than string length',
BETWNSTR(
STRING_IN => 'abcdefg',
START_IN => 3,
END_IN => 200)
,
'cdefg'
);
END ut_betwnstr;
END UT_BETWNSTR;
而函数名BETWNSTR是这样的:
create or replace
FUNCTION BETWNSTR (
string_in IN VARCHAR2,
start_in IN INTEGER,
end_in IN INTEGER
)
RETURN VARCHAR2
IS
l_start PLS_INTEGER := start_in;
BEGIN
IF l_start = 0
THEN
l_start := 1;
END IF;
RETURN (SUBSTR (string_in, l_start, end_in - l_start + 1));
END;
在我的 C 盘中,我放了一个文件名 BETWNSTR.sql,其中包含:
connect hr/hr
SET SERVEROUTPUT ON
EXEC UTPLSQL.TEST('BETWNSTR',Recompile_in=>FALSE);
exit
这是我的批处理文件(也在 C 盘中),名称为 try.bat,其中包含:
@sqlplus /nolog @C:\betwnstr.sql
echo %errorlevel%
if errorlevel 0 goto Success
echo You Got Error
:Success
echo Good Job!!
pause
好的,错误来了
当我运行 try.bat 时,它会返回我故意放的大 FAILURE 结果
PROCEDURE ut_BETWNSTR IS
BEGIN
utAssert.eq (
'Typical valid usage',
BETWNSTR(
STRING_IN => 'abcdefg',
START_IN => 3,
END_IN => 5)
,
'abc'
);
而不是
PROCEDURE ut_BETWNSTR IS
BEGIN
utAssert.eq (
'Typical valid usage',
BETWNSTR(
STRING_IN => 'abcdefg',
START_IN => 3,
END_IN => 5)
,
'cde'
);
我这样做是故意的,所以我希望 cmd 会回显:
You Got Error
因为我的代码中有错误..但是错误级别正在回显 0,这意味着它是成功的..
我知道,我的代码现在取决于 errorlevel..当 errorlevel 为 0 时,它会回显 Good Job..
我现在想要的是,当我运行批处理文件时,当它遇到错误时,我可以回显 You Got Error 消息..
当错误级别始终显示为 0 时,我如何回显“您遇到错误”消息..
简而言之,我想在不依赖错误级别的情况下回显错误消息..
我希望任何解决我问题的人都可以回答我的问题..
提前致谢!
【问题讨论】:
所以你的实际问题是“如何处理调用 sqlplus 的批处理文件中的错误,因为 sqlplus 没有在错误或失败时设置 ERRRORLEVEL?” 感谢您的评论,@KenWhite 【参考方案1】:所有之前的答案都回答了:“如何处理调用 sqlplus 的批处理文件中的错误,当 sqlplus 没有在错误或失败时设置 ERRRORLEVEL?”
但您实际上可以使用以下 sqlplus 命令以非零退出代码使 sqlplus 在错误时退出:
whenever sqlerror exit sql.sqlcode
另见http://voidtech.wordpress.com/2013/03/06/execute-an-script-with-sqlplus-and-get-the-exitcode-to-the-environment/ 我在装有Oracle 10g 的windows 机器上以这种方式使用它:
sqlplus some_user/pw@tns_name @ some_script.sql
IF %ERRORLEVEL% NEQ 0 call some_action_on_error.vbs
【讨论】:
【参考方案2】:我不确定这是否可行,但也许值得一试。 (我没有 Windows 机器,所以无法测试,但看起来差不多)这将取决于 sql 写入标准输出的能力。我不了解 Oracle,所以我不知道你是否可以让它做到这一点,但如果可以的话,如果你知道错误/警告消息的标准模式,下面的小技巧应该可以工作。如果 /nolog 停止打印到标准输出,请将其从下面的 sn-p 中取出。值得一试。祝你好运! :)
setlocal enabledelayedexpansion
some_text_signifying_error=whatever you can get sql to display to Standard Output
set msg=''
For 'eol=; tokens=1 delims=' %%e in ('@sqlplus /nolog @C:\betwnstr.sql ^| findstr /i /c:"!some_text_signifying_error!"') do (
set msg=!msg! %%e
)
if NOT !msg!='' echo !msg!
【讨论】:
查看以下链接的第一个响应,它使用了我建议的相同方法,并添加了一些额外的 sqlplus 内容来帮助您填补空白...dbforums.com/oracle/1044496-sqlplus-return-value-help.html 看起来你的回答对我有很大帮助..现在我正在尝试消化它..我让你知道它是否成功.. 我很高兴听到它在某种程度上有所帮助。我希望我能提供更多帮助,但我的预言机经验为 0 >. 好的,现在我可以发现我的代码失败了! =D 我正在使用 For /F .. 如果它检测到失败,我可以知道如何回显,它会回显 You Got Prob,如果它没有检测到任何故障,它将返回无 ..在此之前我取决于错误级别回显errorMessage..现在我不再依赖于错误级别,这就是为什么我在这里有点困惑..谢谢! 好的,这是我目前的代码: setlocal enabledelayedexpansion For /F "tokens=* delims= " %%e in ('@sqlplus /nolog @C:\btwn.sql ^| findstr / i /c:"FAILURE"') 做 ( set msg=!msg! %%e ) PAUSE以上是关于如何处理调用 sqlplus 的批处理文件中的错误,因为 sqlplus 没有在错误或失败时设置 ERRORLEVEL?的主要内容,如果未能解决你的问题,请参考以下文章