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

时间:2009-10-26 15:47:30

标签: sql oracle plsql liquibase

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

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

某种东西

  

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

     

删除User / Secuence(如果存在)

据我所知,我有以下选择:

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

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

5 个答案:

答案 0 :(得分:13)

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

<changeSet failOnError="false">
   <createSequence sequenceName="new_sequence"/>
</changeSet>

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

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

<changeSet>
   <preconditions onFail="MARK_RAN"><not><sequenceExists/></not></preconditions>
   <createSequence name="new_sequence"/>
</changeSet>

目前没有userExists前提条件,但您可以创建自定义前提条件或回退到前提条件。有关文档

,请参阅http://www.liquibase.org/documentation/preconditions.html

答案 1 :(得分: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;
/

答案 2 :(得分:2)

我只使用PL / SQL匿名块。

begin
   for x in (select sequence_name
             from   user_sequences
              where sequence_name in ('SEQ1','SEQ2' ... 'SEQn'))
   loop
      execute immediate 'drop sequence '||x.sequence_name;
   end loop;
end;
/

答案 3 :(得分:1)

根据我的经验,基于Liquibase 3.5.1行为,当使用failOnError =“false”时,如果操作失败,则changeSet不会被记录为“RAN”。 对我来说,这似乎是一个错误,而Nathan的回答似乎不正确?

  

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

即:它不会将它们标记为已运行!

答案 4 :(得分:1)

liquibase前提条件没有为我检查现有序列。因此,经过多次尝试,我尝试了简单的<changeSet id="test-id"><sql> DROP SEQUENCE IF EXISTS "TABLENAME_ID_seq"; </sql></changeSet>