代码之家  ›  专栏  ›  技术社区  ›  Tom

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

  •  7
  • Tom  · 技术社区  · 15 年前

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

    甲骨文有没有防止错误发生的方法?

    类似的东西

    如果不存在,则创建用户/序列

    删除用户/联系人(如果存在)

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

    • 编写plsql脚本
    • 使用禁酒环境。
    • 使用液化的先决条件,但这意味着太多的工作。

    任何想法/想法都将非常感激。

    5 回复  |  直到 6 年前
        1
  •  13
  •   arulraj.net    9 年前

    LyQueBasic有一个ValeNoRebug属性,它可以在包含可能失败的调用的变更集上设置为false。

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

    这允许您使用简单的create user、create sequence、drop user和drop sequence变更集,如果语句由于用户/序列存在/不存在而引发错误,则它们仍将标记为已运行,更新将继续。

    这种方法的缺点是,如果由于其他原因(错误的权限、连接失败、无效的sql等)而出错,它还会将它们标记为run并继续,更准确的方法是使用前置条件,如:

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

    目前没有用户存在的前提条件,但是您可以创建自定义的先决条件或回落到前提条件。见 http://www.liquibase.org/documentation/preconditions.html 用于文档

        2
  •  5
  •   Rob van Laarhoven    15 年前

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

    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;
    /
    
        3
  •  2
  •   David Aldridge    15 年前

    我只需要使用一个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;
    /
    
        4
  •  1
  •   consultantleon    8 年前

    根据我的经验,基于Liquibase 3.5.1行为,当使用failonerror=“false”时,如果操作失败,变更集不会被记录为“运行”。 对我来说这似乎是个错误,内森的回答似乎不正确?

    这种方法的缺点是它也会将它们标记为ran 如果由于其他原因出错(权限错误, 连接失败、无效的sql等)更准确的方法是 使用先决条件,如下所示:

    也就是说:它不会把他们标记为逃跑!

        5
  •  1
  •   Ramz_the_dev    6 年前

    解酒的先决条件没有为我检查现有的序列。所以,经过多次尝试,我尝试了简单的 <changeSet id="test-id"><sql> DROP SEQUENCE IF EXISTS "TABLENAME_ID_seq"; </sql></changeSet>