【问题标题】:Error Handling in an Oracle ScriptOracle 脚本中的错误处理
【发布时间】:2010-08-07 21:21:16
【问题描述】:

我已经尝试解决这个问题一段时间了,我认为是时候寻求帮助了。我正在构建一个模式配置脚本,我想添加一些脚本输出和错误处理。这个想法是脚本输出窗口只会向我显示关键消息而没有所有噪音。

Create Temporary Error Table
Begin Transaction

-- begin work block
Print "Doing some types of work"
-- do work here

If Error and Active Transactions > 0 Then Rollback
If Active Transactions = 0 Then Insert Error In Temp Error Table and Start Another Transaction
-- end work block

-- once all all work complete
If Active Transactions > 0 Then Commit Transactions

在 SQL Server 世界中,我通常只使用 Red Gate's SQL Packager 来完成此操作,这已经弄清楚了(提示,提示 Red Gate - 我们需要一个 Oracle 版本:))。有什么想法可以从 Oracle 开始获得类似的东西吗?

【问题讨论】:

  • 我正在构建模式配置脚本 如果您的意思是创建/更改表等;回滚无济于事。在 Oracle 中,DDL 命令提交当前事务,如果一个未完成,则在事务中运行自身,并在成功时提交,在失败时回滚。因此在运行 DDL 命令后不会有未完成的事务。唯一的例外是如果存在解析错误,那么数据库不知道它应该运行 DDL 命令,并且不会执行第一次隐式提交,也不会为 DDL 启动事务。这与 SQL Server 非常不同。
  • 我的评论没有提供答案,它只是为了指出一个你可能知道也可能不知道的陷阱。
  • @Shannon - 谢谢,你不能进行包含 DDL 的范围更广的事务真的很糟糕。如果出现问题,它会使数据库处于半生不熟的状态,从而使配置过程中的错误处理变得更加困难。
  • :) 为了回答您的提示,我们还没有适用于 Oracle 的 Packager 产品,但您可以尝试适用于 Oracle 的 Schema Compare 和适用于 Oracle 的数据比较:red-gate.com/products/schema_compare_for_oracle/index.htm

标签: oracle plsql


【解决方案1】:

在 Oracle 中,您定义事务边界 -- 完成后提交,每个语句都是原子的。

如果您使用的是 SQL*Plus,并且如果出现任何问题,您根本不希望提交任何内容,您可以在 SQL 脚本中添加以下内容:

SET ECHO ON
SPOOL /some/path/to/logfile.log
WHENEVER SQLERROR EXIT SQL.CODE ROLLBACK

-- run your code or DML statements

COMMIT;
EXIT;

这将在第一次遇到错误时将其轰出,因此错误语句将在日志文件的末尾。它还将回滚任何更改,因此只要没有任何 COMMITs(或导致它们的语句,如 CREATE, ALTER, DROP, GRANTREVOKE),那么整个升级就是全有或全无。

【讨论】:

    【解决方案2】:

    在我见过的大多数情况下,此类(重复)任务是使用脚本自动完成的。

    我们目前的一种方法是使用 UNIX 脚本运行给定目录中的所有 .sql 文件并生成一个 .log 文件。在过程结束时,我们 grep 日志文件并查看是否有任何错误。

    您不需要手动打印任何错误,因为 sqlplus 已经打印出错误并在日志文件中捕获。

    下面是一个非常简单的例子……

    .ksh 文件

    #!/usr/bin/ksh
    echo "Starting provisioning script.."
    
    sqlplus scott/tiger@oracle102 > file1.log << !
    @file1.sql
    @file1.sql
    !
    
    echo "end of provisioning script"
    

    还有 file1.sql 的内容(在本例中位于同一目录中)

    create table test123(
       id number,
       name varchar2(200)
    );
    

    当我运行这个脚本时,第一个创建成功,第二个失败..日志文件将是.. like..

    SQL*Plus: Release 10.2.0.4.0 - Production on Fri Aug 6 20:44:08 2010
    
    Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.
    
    
    Connected to:
    Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
    With the Partitioning, OLAP, Data Mining and Real Application Testing options
    
    SQL>
    Table created.
    
    SQL> create table test123(
                 *
    ERROR at line 1:
    ORA-00955: name is already used by an existing object
    
    
    SQL> Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
    With the Partitioning, OLAP, Data Mining and Real Application Testing options
    

    您可以按照这些思路准备一个脚本......然后在日志文件中查找任何错误......一旦执行完成。您可以使用各种 sqlplus 会话命令来摆脱所有不需要的 cmets 等。

    我不知道有任何自动化工具可以做到这一点。我一直这样做的原因

    希望这会有所帮助...

    【讨论】:

    • 如果可能,我会尽量避免混合 shell 脚本。创建太多依赖项。
    猜你喜欢
    • 2014-05-21
    • 1970-01-01
    • 1970-01-01
    • 2011-10-25
    • 1970-01-01
    • 1970-01-01
    • 2011-05-11
    • 2015-05-23
    • 1970-01-01
    相关资源
    最近更新 更多