Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent error when dropping not existing sequences, creating existing users

I have a bunch of sql scripts that create / drop sequences, users and other objects. I'm running these scripts through liquibase, but they fail because oracle complains when I try to drop a non existing sequence, or create an existing user.

Is there an oracle way to prevent errors from happening?

Something of the sort

Create User / Sequence if not exists

Drop User/ Secuence if exists

As far as I know, I have these options:

  • Write a plsql script
  • Use liquibase contexts.
  • Use liquibase preconditions, but this would mean too much work.

Any thoughts / ideas will be greatly appreciated.

like image 712
Tom Avatar asked Oct 26 '09 15:10

Tom


People also ask

What happens to sequences when the table is dropped?

A table's triggers are dropped when you drop the table. A standalone sequence created with create sequence is not associated with any table, but an internal sequence that is part of an identity column is dropped with the table, so it depends which you mean.

How do you drop a sequence if it exists in Oracle?

Use the DROP SEQUENCE statement to remove a sequence from the database. You can also use this statement to restart a sequence by dropping and then re-creating it.

How do I drop all sequences in SQL?

select 'drop table ' || table_name || ';' from user_tables; select 'drop sequence ' || sequence_name || ';' from user_sequences; This will generate the script to drop all the tables and sequences.

How do you drop a sequence in DBMS?

The syntax to a drop a sequence in Oracle is: DROP SEQUENCE sequence_name; sequence_name. The name of the sequence that you wish to drop.


2 Answers

Liquibase has a failOnError attribute you can set to false on changeSets that include a call that could fail.

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

This allows you to have simple create user, create sequence, drop user, and drop sequence changeSets and if the statement throws an error because they users/sequences exist/don't exist they will still be marked as ran and the update will continue.

The downside of this approach is that it will also mark them as ran and continue if they error for some other reason (bad permissions, connection failure, invalid SQL, etc.) The more accurate approach is to use preconditions, like this:

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

There is no userExists precondition currently, but you can create custom preconditions or fall back to the precondition. See http://www.liquibase.org/documentation/preconditions.html for documentation

like image 190
Nathan Voxland Avatar answered Oct 20 '22 22:10

Nathan Voxland


Write a function do_ddl similar to this and catch all exceptions you want to catch:

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;
/
like image 41
Rob van Laarhoven Avatar answered Oct 20 '22 22:10

Rob van Laarhoven