【问题标题】:Managing error handling while running sqlplus from shell scripts从 shell 脚本运行 sqlplus 时管理错误处理
【发布时间】:2013-01-21 22:47:56
【问题描述】:
#!/bin/sh

echo "Please enter evaluate database username"
read eval_user
echo "Please enter evaluate database password"
read eval_pass
echo "Please enter the database name"
read db_name

LOGFILE=shell_log.txt

$ORACLE_HOME/bin/sqlplus -s /nolog <<-EOF>> ${LOGFILE}
connect $eval_user/$eval_pass@$db_name
WHENEVER OSERROR EXIT 9;
WHENEVER SQLERROR EXIT SQL.SQLCODE;
DBMS_OUTPUT.put_line('Connected to db');
EOF

if [ $? != 0 ]
then 
echo "The upgrade script failed. Please refer to the log results.txt for more information"
echo "Error code $?"
exit 0;
fi

我正在输入垃圾值,试图强制此脚本失败。但是,令人讨厌的是,它一直在继续前进,而没有提及任何错误代码。这里还需要做什么?

【问题讨论】:

  • 您在哪个操作系统用户帐户下运行?脚本登录到什么数据库?
  • 我试过你的脚本,日志文件正在捕获错误代码。这是从日志文件中获取的内容:ERROR: ORA-01017: invalid username/password; logon denied SP2-0734: unknown command beginning "DBMS_OUTPU..." - rest of line ignored.
  • 请问,当您执行脚本时,您在日志文件中得到了什么?

标签: oracle shell sqlplus aix


【解决方案1】:

您的whenever 语句可能在与数据库的连接建立后执行(因为您后来提到了它们)。试试下面的代码:-

$ORACLE_HOME/bin/sqlplus -s /nolog <<-EOF>> ${LOGFILE}
WHENEVER OSERROR EXIT 9;
WHENEVER SQLERROR EXIT SQL.SQLCODE;
connect $eval_user/$eval_pass@$db_name
DBMS_OUTPUT.put_line('Connected to db');
EOF

【讨论】:

  • 我真的无法解析这句话。
  • @Maaark,现在试试。我编辑了答案。
【解决方案2】:

您输入虚假值的事实可能仅与登录有关。然后: Check database connectivity using Shell script

WHENEVER ... 用于 SQL 脚本执行期间的错误。一旦你成功连接到你的脚本(我认为这是你现在的问题),你应该得到WHENEVER ERROR 管理的那种错误,因为你忘记了EXECDBMS_OUTPUT 的行。

【讨论】:

    【解决方案3】:

    麦克斯说的是对的。试试这个修改后的脚本

    #!/bin/sh
    
    echo "Please enter evaluate database username"
    read eval_user
    echo "Please enter evaluate database password"
    read eval_pass
    echo "Please enter the database name"
    read db_name
    
    LOGFILE=shell_log.txt
    
    sqlplus -s /nolog <<-EOF>> ${LOGFILE}
    WHENEVER OSERROR EXIT 9;
    WHENEVER SQLERROR EXIT SQL.SQLCODE;
    connect $eval_user/$eval_pass@$db_name
    DBMS_OUTPUT.put_line('Connected to db');
    EOF
    
    sql_return_code=$?
    
    if [ $sql_return_code != 0 ]
    then
    echo "The upgrade script failed. Please refer to the log results.txt for more information"
    echo "Error code $sql_return_code"
    exit 0;
    fi
    

    请注意使用 sql_return_code 来捕获 SQLPLUS 返回码。

    DBMS_OUTPUT 语句应该失败并出现错误 - “SP2-0734:未知命令开始...”。您可以在日志文件中找到错误消息。

    可以使用错误记录工具捕获 SQLPLUS 11g 中的 sp2 错误。请查看http://tkyte.blogspot.co.uk/2010/04/new-thing-about-sqlplus.html 了解更多信息。

    【讨论】:

    • 我只得到错误代码 122,而不是实际的 db 错误消息。你知道捕获输出的方法吗?
    • 错误信息被重定向到“shell_log.txt”。查看当前目录中的该文件。如果要在 shell 脚本中捕获输出,则需要删除重定向并将 SQLPLUS 的输出分配给变量。例如:- SQL_RESULT=$(sqlplus -s /nolog &lt;&lt; EOF WHENEVER SQLERROR EXIT FAILURE WHENEVER OSERROR EXIT FAILURE SET SERVEROUTPUT ON connect $eval_user/$eval_pass@$db_name exec DBMS_OUTPUT.put_line('Connected to db'); exit EOF )
    • UNIX 操作系统中的 Shell 脚本最多可以返回 255 个代码。所以我不明白 WHENEVER SQLERROR EXIT SQL.SQLCODE;可以正确返回 255 以上的 SQL 代码吗?例如。 ORA-12703 不支持此字符集转换 实际上我只是做了一个测试并运行了一个错误的 SQL,该 SQL 失败并出现 ORA-00936: missing expression bad sqlplus returned 168 (!) 所以实际的返回码 936 被包装了,剩下的只是回来。 936%256=168。这不是一个正确的答案。
    【解决方案4】:

    您只能捕获 sql 错误或 os 错误。 dbms_output 将在 sqlplus 级别本身失败,因此无论何时错误设置都不会影响它。

    【讨论】:

      【解决方案5】:

      阿吉的回答与

      WHENEVER SQLERROR EXIT SQL.SQLCODE;
      

      然后使用

      sql_return_code=$?
      

      不正确(或在大多数情况下不正确)。请参阅下面的详细信息。


      UNIX 操作系统中的 Shell 脚本最多可以返回 255 个代码。 例如。 “ORA-12703 不支持此字符集转换”返回码应为 12703,但它不适合 UNIX 8 位返回码。
      实际上,我只是做了一个测试并运行了一个错误的 SQL,该 SQL 失败并显示“ORA-00936:缺少表达式”-
      sqlplus 返回 168 (!)。
      所以实际的返回码 936 被包装在 256 处,剩下的就被返回了。 936%256=168。


      这可能在 Windows 上可以工作(未经测试),但在 UNIX 上则不行(如上文所述进行了测试)。


      唯一可靠的机制可能是将结果假脱机到日志文件中,然后执行类似的操作

      tail -n 25 spool.log | egrep "ORA-" | tail -n 1 | cut -d: -f1 | cut -d- -f2
      

      所以它会 grep 假脱机日志文件,然后剪切实际最新的 ORA 代码。

      【讨论】:

      • OP 可以只使用WHENEVER SQLERROR EXIT 10; 或其他东西。但好点。 SQLCODE 可能会 mod 256 等于 0!
      猜你喜欢
      • 2016-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多