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