Reputation: 1088
For my application that uses an Oracle 8 DB, I am providing an SQL script to setup stuff like triggers, sequences etc., which can be copied and pasted into SQL*Plus. I would like the script to not stop with an error if a sequence that I am trying to create already exists. For a Trigger this can easily be done using "create or replace trigger ...", but for a sequence this does not work. I also tried ""if not exists mysequence then create sequence ..." but it did not too. Is there some alternative?
Alternatively, if this is not possible, is there a way to do a "drop sequence mysequence" without SQL*Plus aborting the script if mysequence does not exist?
Upvotes: 21
Views: 48954
Reputation: 11
DECLARE
lsSeqName VARCHAR2(32 CHAR) := UPPER('MY_SEQUENCE_NAME');
lnSeqCount NUMBER;
BEGIN
-- try to find sequence in data dictionary
SELECT count(1)
INTO lnSeqCount
FROM user_sequences
WHERE UPPER(sequence_name) = lsSeqName;
-- if sequence not found, create it
IF lnSeqCount = 0 THEN
EXECUTE IMMEDIATE 'CREATE SEQUENCE ' || lsSeqName || ' START WITH 1 MINVALUE 1 MAXVALUE 1000000000000000 INCREMENT BY 1 NOCYCLE CACHE 20 NOORDER';
END IF;
END;
/
OR
-- helper method
PROCEDURE createSeqIfNotExists (
isSeqName VARCHAR2
) IS
lnSeqCount NUMBER;
BEGIN
-- try to find sequence in data dictionary
SELECT count(1)
INTO lnSeqCount
FROM user_sequences
WHERE UPPER(sequence_name) = UPPER(isSeqName);
-- if sequence not found, create it
IF lnSeqCount = 0 THEN
EXECUTE IMMEDIATE 'CREATE SEQUENCE ' || UPPER(isSeqName) || ' START WITH 1 MINVALUE 1 MAXVALUE 1000000000000000 INCREMENT BY 1 NOCYCLE CACHE 20 NOORDER';
END IF;
END createSeqIfNotExists;
-- call method
BEGIN
createSeqIfNotExists('MY_SEQUENCE_NAME');
END;
/
Upvotes: 1
Reputation: 2805
DECLARE
v_dummy NUMBER;
BEGIN
-- try to find sequence in data dictionary
SELECT 1
INTO v_dummy
FROM user_sequences
WHERE sequence_name = 'MY_SEQUENCE_NAME';
-- if sequence found, do nothing
EXCEPTION
WHEN no_data_found THEN
-- sequence not found, create it
EXECUTE IMMEDIATE 'create sequence my_sequence_name';
END;
Upvotes: 16
Reputation: 6215
I like:
DECLARE
C NUMBER;
BEGIN
SELECT COUNT(*) INTO C
FROM ALL_TRIGGERS
WHERE OWNER = 'YOUROWNER'
AND TRIGGER_NAME = 'YOURTRIGGER';
IF (C = 0) THEN
EXECUTE IMMEDIATE '
CREATE TRIGGER "YOUROWNER"."YOURTRIGGER"
blah blah blah your trigger blah blah
';
END IF;
END;
/
Upvotes: 5
Reputation: 11925
If you're sure the script will always run under SQL*Plus, you can bracket the CREATE SEQUENCE statements with a directive to continue on error:
WHENEVER SQLERROR CONTINUE
-- create sequences here, ignoring errors
WHENEVER SQLERROR EXIT SQL.SQLCODE
Be aware if there are other errors (permission problems, syntax failures, etc.) in the create sequence statements they will be ignored
Upvotes: 9
Reputation: 2371
You can check user_sequence
table to see whether the sequence being created exists already or not.
Similar to davek
's solution:
The idea is, before creating any sequence, drop the sequence and create it, all in dynamic SQL, create a function, and say when you need to create 10 sequence, let the function take care...
function crt_seq(p_seq_name varchar2)
return boolean
begin
for i in (select 1 from user_sequence where sequence_name = upper(p_seq_name))
loop
---- Already exists. You can drop and recreate or return false to error out
execute immediate 'drop sequence '||p_seq_name;
execute immediate 'create sequence '||p_seq_name||' start with 1 increment
by 1 nocache';
end loop;
return true;
exception
when others then
return false;
end;
You can parametrize all other options and have a elaborate function to create sequence for you.
Upvotes: 1