web-dev-qa-db-fra.com

Y at-il quelque chose comme "sinon créer une séquence ..." dans Oracle SQL?

Pour mon application qui utilise une base de données Oracle 8, je fournis un script SQL pour configurer des éléments tels que des déclencheurs, des séquences, etc., qui peuvent être copiés et collés dans SQL * Plus. J'aimerais que le script ne se termine pas par une erreur si une séquence que j'essaie de créer existe déjà. Pour un déclencheur, cela peut facilement être fait en utilisant "créer ou remplacer le déclencheur ...", mais cela ne fonctionne pas pour une séquence. J'ai aussi essayé "" si ma séquence n'existe pas, alors je crée une séquence ... ", mais ce n'est pas le cas. Y a-t-il une alternative?

Autrement, si cela n’est pas possible, existe-t-il un moyen de faire une "séquence de sauts ma séquence" sans que SQL * Plus abandonne le script si ma séquence n’existe pas?

18
Timo

Si vous êtes certain que le script sera toujours exécuté sous SQL * Plus, vous pouvez encadrer les instructions CREATE SEQUENCE avec une directive pour continuer en cas d'erreur:

WHENEVER SQLERROR CONTINUE
-- create sequences here, ignoring errors
WHENEVER SQLERROR EXIT SQL.SQLCODE

Sachez que s'il y a d'autres erreurs (problèmes d'autorisation, échecs de syntaxe, etc.) dans les instructions de création de séquence, elles seront ignorées.

8
dpbradley
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;
15
jva

J'aime:

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

Vous pouvez vérifier la table user_sequence pour voir si la séquence en cours de création existe déjà ou non.

Semblable à la solution de davek: L'idée est, avant de créer une séquence, de supprimer la séquence et de la créer, le tout en SQL dynamique, créez une fonction et indiquez que lorsque vous devez créer 10 séquences, laissez-la prendre soin ...

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;

Vous pouvez paramétrer toutes les autres options et avoir une fonction élaborée pour créer une séquence pour vous.

1
Guru
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;
/
0
Ondřej Štěpán