Есть ли что-то вроде "if not exist create sequence..." в Oracle SQL?
Для моего приложения, использующего Oracle 8 DB, я предоставляю SQL script для настройки таких вещей, как триггеры, последовательности и т.д., которые можно скопировать и вставить в SQL * Plus. Я хотел бы, чтобы script не останавливался с ошибкой, если последовательность, которую я пытаюсь создать, уже существует. Для триггера это можно легко сделать, используя "создать или заменить триггер...", но для последовательности это не работает. Я также пробовал "если не существует mysequence, тогда создайте последовательность...", но это тоже не так. Есть ли альтернатива?
В противном случае, если это невозможно, существует ли способ сделать "последовательность последовательности mysequence" без SQL * Plus, прервав script, если mysequence не существует?
Ответы
Ответ 1
Если вы уверены, что script всегда будет работать под SQL * Plus, вы можете скопировать инструкции CREATE SEQUENCE с директивой, чтобы продолжить ошибку:
WHENEVER SQLERROR CONTINUE
-- create sequences here, ignoring errors
WHENEVER SQLERROR EXIT SQL.SQLCODE
Помните, что есть другие ошибки (проблемы с разрешениями, сбои синтаксиса и т.д.) в операциях создания последовательности, которые они будут игнорировать.
Ответ 2
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;
Ответ 3
Мне нравится:
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
Вы можете проверить таблицу 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;
Вы можете параметризовать все другие параметры и иметь сложную функцию для создания последовательности для вас.
Ответ 5
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;
/
ИЛИ
-- 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;
/