【问题标题】:How do I exit a script in SQLPlus when an error occurs and return to the SQLPlus prompt, without disconnecting or exiting SQLPlus?如何在发生错误时退出 SQLPlus 中的脚本并返回 SQLPlus 提示符,而不断开或退出 SQLPlus?
【发布时间】:2012-06-27 03:59:17
【问题描述】:

我有一些脚本经常在连接的 SQLPlus 会话中运行。

我需要一种在发生错误时退出脚本的方法, 不会断开或退出 SQLPlus 本身。 100% 的情况下,当发生错误时,连接的 DBA 将需要向会话发出一个或多个命令。 100% 的时间,当发生错误时,稍后在脚本中会有其他 SQLPlus 语句(因此 必须 BEGIN..END; 之外不得执行,否则可能会出现严重问题。

注意:如果您建议WHENEVER SQLERROR EXIT,那么您没有阅读上述文字。这将断开并退出 SQLPlus 除了脚本,这是不可接受的行为。

【问题讨论】:

  • 有趣的是你为什么不把你的脚本分成一个shell/批处理脚本和使用whenever sqlerror exit然后shell脚本错误处理来决定是否继续?
  • 因为在脚本运行之前和/或之后,他们需要执行大量手动操作,包括运行其他脚本,这些脚本特定于情况/环境/数据/等。涉及。这主要是为了修复生产中的问题,当您的网站关闭时,不断被踢出/不得不重新连接比烦人更糟糕。它们不能分解成多个脚本,因为 SQLPlus 命令正在使用 PL/SQL 命令的输出。

标签: oracle sqlplus


【解决方案1】:

我发现了一个有趣的想法here,当与spencer7593 的答案结合使用时,我可以选择性地调用子脚本,我可以将PL/SQL 输出值传递给它。也就是说:

VAR continue number;
EXEC :continue := 1;
BEGIN
   SELECT some_bool_test() INTO :continue FROM dual;
END;

SET termout OFF
COLUMN script_name NEW_VALUE v_script_name
SELECT decode(:continue, 1, 'run_stuff.sql', 'skip.sql') script_name FROM dual;
SET termout ON

@&v_script_name :some_other_values

其中skip.sql 是一个空文本文件。

更新:我已将其中的大部分内容移至 RUN.SQL 文件中,在该文件中我将布尔值(0 或 1)作为 &1 传递,调用成功的脚本名称为&2,然后是传递给被调用脚本的任何其他预期参数。因此,它最终看起来像这样:

VAR continue number;
EXEC :continue := 1;
BEGIN
   SELECT some_bool_test() INTO :continue FROM dual;
END;

@run.sql :continue 'run_stuff.sql' :some_other_values

【讨论】:

  • 很遗憾,一个成本与 Oracle 一样高的数据库让您跳过这么多圈。不是吗?
  • 抱歉,误投了反对票。请编辑,以便我可以恢复我的投票。
【解决方案2】:

这是不可能的。

SQLPlus 不提供对脚本执行的那种级别的控制。

显然,您需要避免使用WHENEVER SQLERROR EXIT ... 命令。

由于使用 PL/SQL 引发的异常(错误),可以有条件地控制哪些 SQL 语句执行或不执行。但这并没有解决 SQLPlus 命令(不能从 PL/SQL 块中执行)。

DECLARE
  lb_continue BOOLEAN;
BEGIN
  lb_continue := TRUE;
  BEGIN 

    sql statement

  EXCEPTION
    WHEN OTHERS THEN
      lb_continue = FALSE;
  END;
  IF lb_continue THEN
  BEGIN

    sql statements

  EXCEPTION
    WHEN OTHERS THEN
      lb_continue := FALSE;
  END; 
END;

当然,这种方法有其自身的局限性和问题。任何 DDL 语句都需要动态调用;最简单的方法是EXECUTE IMMEDIATE statement

最大的问题(就您而言)是无法从 PL/SQL 块内执行 SQLPlus 命令。

【讨论】:

  • 我很困惑,为什么当您将 SQLPlus 作为命令行(而不是一次性连接脚本运行断开连接)运行时,这没有作为默认行为实现.除了返回到 SQLPLus 命令提示符之外,我想不出任何我想要任何其他行为的情况。
  • 我不确定您所说的默认行为是什么意思。您的意思是为什么 SQL*Plus 中没有“转到当前脚本的结尾”命令?
【解决方案3】:

您不能退出脚本并停留在 SQL*Plus 中,但可以停止执行。这不是很漂亮,但假设您可以修改脚本以添加控制流,那么您可以使用绑定变量来做到这一点。

set serveroutput on

var flag char;
exec :flag := 'Y';

begin
    if :flag != 'Y' then
        raise program_error;
    end if;
    dbms_output.put_line('Doing some work');
    /* Check for some error condition */
    if 0 != 1 then
        raise program_error;
    end if;
    /* Only reach this if earlier statements didn't fail
     * but could wrap in another flag check if needed */
    dbms_output.put_line('Doing some more work');
    exception
        when program_error then
            dbms_output.put_line(sqlerrm);
            :flag := 'N';
        when others then
            /* Real exception handling, obviously */
            dbms_output.put_line(sqlerrm);    
            :flag := 'N';
end;
/

-- DML only does anything if flag stayed Y
select sysdate from dual
where :flag = 'Y';

-- Optional status message at the end of the script, for DBA info
set feedback off
set head off
select 'Something went wrong' from dual where :flag != 'Y';
set feedback on
set head on

执行时:

SQL> @script

PL/SQL procedure successfully completed.

Doing some work
ORA-06501: PL/SQL: program error

PL/SQL procedure successfully completed.


no rows selected


Something went wrong
SQL> 

脚本中的任何 PL/SQL 块都可以在开始时检查标志状态,并引发program_error(就像一个方便的预定义异常)以跳出。 PL/SQL 块中的任何错误都可以直接或在异常处理程序中更新绑定变量标志。并且任何非 PL/SQL DML 都可以有一个额外的 where 子句来检查标志状态,因此如果在到达该语句时它已设置为 N,则不会进行任何工作。 (对于insert,我想这意味着不使用values 表单)。

这不能做的是处理任何错误来自普通 SQL 语句,但我不确定这是否是一个问题。如果是,那么可能需要将这些更改为 PL/SQL 块内的动态 SQL。

【讨论】:

    【解决方案4】:

    我知道它很旧,但是 SQL 脚本开头的这两条指令可以完成工作:

    当 SQLERROR 退出失败回滚时

    当 OSERROR 退出失败回滚时

    【讨论】:

    • 那些将断开连接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-16
    • 1970-01-01
    • 2014-02-04
    • 2010-11-27
    • 2014-05-12
    • 2017-01-31
    • 1970-01-01
    相关资源
    最近更新 更多