删除不存在的序列时,防止出错,创建现有用户

Tom*_*Tom 7 sql oracle plsql liquibase

我有一堆sql脚本,可以创建/删除序列,用户和其他对象.我通过liquibase运行这些脚本,但它们失败了,因为当我尝试删除不存在的序列或创建现有用户时,oracle会抱怨.

是否有一种预防错误的oracle方法?

某种东西

创建用户/序列(如果不存在)

如果存在,则删除User/Secuence

据我所知,我有这些选择:

  • 写一个plsql脚本
  • 使用liquibase上下文.
  • 使用liquibase前提条件,但这意味着太多的工作.

任何想法/想法将不胜感激.

Nat*_*and 15

Liquibase有一个failOnError属性,你可以在包含可能失败的调用的changeSets上设置为false.

<changeSet failOnError="false">
   <createSequence sequenceName="new_sequence"/>
</changeSet>
Run Code Online (Sandbox Code Playgroud)

这允许您具有简单的创建用户,创建序列,删除用户和删除序列changeSet,并且如果语句因为用户/序列存在/不存在而引发错误,则它们仍将被标记为已运行并且更新将继续.

这种方法的缺点是,如果由于某些其他原因(错误的权限,连接失败,无效的SQL等)出错,它也会将它们标记为已运行并继续运行.更准确的方法是使用前置条件,如下所示:

<changeSet>
   <preconditions onFail="MARK_RAN"><not><sequenceExists/></not></preconditions>
   <createSequence name="new_sequence"/>
</changeSet>
Run Code Online (Sandbox Code Playgroud)

当前没有userExists前提条件,但您可以创建自定义前提条件或回退到前提条件.有关文档,请参阅http://www.liquibase.org/documentation/preconditions.html

  • 是的你应该.ChangeSets尝试是事务性的,但数据库通常会在创建序列等DDL调用上自动提交.liquibase用于跟踪运行的changeSets的databasechangelog表只跟踪运行的整个变更集,因此如果在单个changeSet中有15个创建序列调用,并且由于某种原因第8个抛出错误,则liquibase更新将在第一次运行时失败由于该错误,从那时起,changeSet将始终失败,因为第一个序列已经存在.因此,最好的方法是每个changeSet有一个DDL调用. (2认同)

Rob*_*ebe 5

编写一个与此类似的函数do_ddl并捕获您想要捕获的所有异常:

DECLARE
   allready_null EXCEPTION;
   PRAGMA EXCEPTION_INIT(allready_null, -1451);
BEGIN
   execute immediate 'ALTER TABLE TAB MODIFY(COL  NULL)';
EXCEPTION
   WHEN allready_null THEN
      null; -- handle the error
END;
/
Run Code Online (Sandbox Code Playgroud)