Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 防止删除不存在的序列时出错,创建现有用户_Sql_Oracle_Plsql_Liquibase - Fatal编程技术网

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

Sql 防止删除不存在的序列时出错,创建现有用户,sql,oracle,plsql,liquibase,Sql,Oracle,Plsql,Liquibase,我有一堆sql脚本,可以创建/删除序列、用户和其他对象。我正在通过liquibase运行这些脚本,但它们失败了,因为当我尝试删除不存在的序列或创建现有用户时,oracle会抱怨 oracle是否有防止错误发生的方法 类似的东西 创建用户/序列(如果不存在) 如果存在,请删除用户/密码 据我所知,我有以下选择: 编写一个plsql脚本 使用液化上下文 使用liquibase先决条件,但这意味着要做太多的工作 如果您有任何想法/想法,我们将不胜感激。编写一个类似于此的函数,并捕获您想要捕获的所有

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

oracle是否有防止错误发生的方法

类似的东西

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

如果存在,请删除用户/密码

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

  • 编写一个plsql脚本
  • 使用液化上下文
  • 使用liquibase先决条件,但这意味着要做太多的工作

如果您有任何想法/想法,我们将不胜感激。

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

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;
/

我只需要使用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;
/

Liquibase有一个failOnError属性,您可以在包含可能失败的调用的变更集上将其设置为false

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

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

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

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


当前没有userExists前提条件,但您可以创建自定义前提条件或退回到该前提条件。根据我的经验,在使用failOnError=“false”时,基于Liquibase 3.5.1行为,如果操作失败,变更集不会被记录为“已运行”,请参阅文档。 对我来说,这似乎是一个错误,内森的回答似乎不正确

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

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

即:它不会将它们标记为ran

液化先决条件没有为我检查现有序列。因此,在多次尝试之后,我尝试了simple


如果存在“TABLENAME\u ID\u seq”,则删除序列

我考虑了先决条件,但仍然存在一个疑问:如果我有N个create sequence语句,我是否应该创建相同数量的变更集?是的,您应该这样做。变更集试图是事务性的,但数据库通常在DDL调用(如create sequence)时自动提交。liquibase用于跟踪运行的变更集的databasechangelog表只跟踪运行的整个变更集,因此如果在单个变更集中有15个create sequence调用,并且由于某种原因第8个调用抛出错误,liquibase更新将在第一次运行时因该错误而失败,从那时起,变更集将始终失败,因为第一个序列已经存在。因此,最好的方法是对每个变更集进行一次DDL调用。liquibase 3.4.2的语法已更改,name属性现在为“sequenceName”