Есть ли что-то вроде «если не существует, создать последовательность ...» в Oracle SQL? - PullRequest
18 голосов
/ 11 апреля 2010

Для моего приложения, использующего БД Oracle 8, я предоставляю сценарий SQL для настройки таких вещей, как триггеры, последовательности и т. Д., Которые можно скопировать и вставить в SQL * Plus. Я хотел бы, чтобы скрипт не останавливался с ошибкой, если последовательность, которую я пытаюсь создать, уже существует. Для триггера это легко сделать с помощью «создать или заменить триггер ...», но для последовательности это не работает. Я также пробовал "" если не существует mysequence, то создайте последовательность ... ", но это не так. Есть ли какая-нибудь альтернатива?

В качестве альтернативы, если это невозможно, есть ли способ выполнить «mysequence последовательности отбрасывания» без SQL * Plus, прервав сценарий, если mysequence не существует?

Ответы [ 5 ]

15 голосов
/ 12 апреля 2010
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;
8 голосов
/ 11 апреля 2010

Если вы уверены, что скрипт всегда будет работать под SQL * Plus, вы можете заключить операторы CREATE SEQUENCE в директиву для продолжения при ошибке:

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

Помните, что в инструкциях создания последовательности есть другие ошибки (проблемы с правами доступа, ошибки синтаксиса и т. Д.), Которые они будут игнорироваться

4 голосов
/ 29 июля 2011

Мне нравится:

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;
/
1 голос
/ 11 апреля 2010

Вы можете проверить таблицу user_sequence, чтобы увидеть, существует ли уже созданная последовательность или нет.

Аналогично решению davek: Идея состоит в том, чтобы перед созданием какой-либо последовательности отбросить последовательность и создать ее, все в динамическом SQL, создать функцию и сказать, что когда вам нужно создать 10 последовательностей, пусть функция позаботится ...

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;

Вы можете параметризовать все остальные параметры и иметь сложную функцию для создания последовательности для вас.

0 голосов
/ 21 сентября 2017
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;
/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...