2010-04-11 7 views
16

Für meine Anwendung, die eine Oracle 8 DB verwendet, stelle ich ein SQL-Skript zur Verfügung, um Dinge wie Trigger, Sequenzen usw. einzurichten, die kopiert und in SQL * Plus eingefügt werden können. Ich möchte, dass das Skript nicht mit einem Fehler beendet wird, wenn eine Sequenz, die ich erstellen möchte, bereits existiert. Für einen Trigger kann dies einfach mit "Trigger erstellen oder ersetzen ..." durchgeführt werden, aber für eine Sequenz funktioniert das nicht. Ich habe auch versucht "", wenn nicht existiert meine Sequenz dann Sequenz erstellen ... "aber es nicht auch. Gibt es eine Alternative?Gibt es in Oracle SQL etwas wie "Wenn nicht existiert, erstellen Sie eine Sequenz ..."?

Alternativ, wenn dies nicht möglich ist, gibt es eine Möglichkeit, eine" drop sequence mysequence "ohne SQL * plus Abbruchs das Skript, wenn mysequence existiert nicht

+0

Wie das Vorhandensein einer AUTOINCREMENT Funktion in Oracle würde dazu beitragen, zu lösen, was eindeutig ein Problem Quellcodeverwaltung/Konfigurationsmanagement ist? – APC

+0

@APC: Entschuldigung, ich verstehe nicht. Kannst du das genauer erklären? Was ich meinte ist: Alles was ich für einen Tisch brauche ist ein Autoinkrementfeld. In z.B. SQL Server Ich definiere gerade die Spalte als autoinc Feld, und ich bin fertig. In Oracle muss ich eine numerische Spalte erstellen, dann eine Sequenz und dann einen Auslöser, um diese Sequenz zu benutzen, um meine Spalte zu füllen. Das scheint mir nicht sehr geradlinig zu sein. – Timo

+0

Mein Punkt ist, wenn Sie eine ordnungsgemäße Schema-Verwaltung an Ort und Stelle hätten, müssten Sie die vorherige Existenz einer Sequenz nicht behandeln, weil Sie nur eine CREATE SEQUENCE-Anweisung gegen Datenbanken ausführen würden, von denen Sie wussten, dass diese Sequenz nicht existierte. – APC

Antwort

7

Wenn Sie das Skript sind sicher immer unter SQL * Plus ausführen, können Sie die SEQUENCE-Anweisungen mit einer Richtlinie CREATE Klammer auf Fehler fortzusetzen:

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

Beachten Sie, wenn es andere Fehler (Erlaubnis Probleme, Syntaxfehler, etc.) in den erstellen Sequenz Aussagen werden sie

+0

Schön, ich wusste nicht über diese Richtlinie. Vielen Dank! – Timo

1

Sie user_sequence Tabelle überprüfen, um zu sehen, ob die Sequenz existiert bereits erstellt wird oder nicht

Ähnlich davek‚s Lösung:. die Idee ist, , bevor Sie eine Sequenz erstellen, legen Sie die Sequenz ab und erstellen Sie sie, alles in dynamischem SQL, erstellen Sie eine Funktion und sagen Sie, wenn Sie 10 Sequenz erstellen müssen, lassen Sie die Fu nction kümmert ...

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; 

Sie können alle andere Optionen parametrisieren und einen aufwendigen Funktionsablauf für Sie zu erstellen haben.

+0

Ich muss zugeben, ich Bin ein solcher Neuling zu Oracle, ich weiß nicht einmal, wo ich diese Funktion definieren und wie ich sie aus meinem SQL-Skript herausbekomme, aber meine Bücher über Oracle sind bereits auf meinem Schreibtisch, also wird mir deine Antwort wahrscheinlich helfen, wenn ich mehr weiß :-) Vielen Dank. – Timo

+1

Warnung: Wenn Sie Code (z. B. Pakete) haben, der die Sequenz verwendet, werden diese ungültig gemacht. Sie können auch Probleme mit der Sperrung haben, wenn diese Pakete beim Ausführen dieses Codes verwendet werden. Oh, und wenn die Sequenz bereits existierte und verwendet wurde, erhalten Sie doppelte Werte. –

+0

Ok, danke. – Timo

11
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; 
+1

Netter Versuch, aber in dieser Form wird es nicht funktionieren. Sie haben ein Groß-/Kleinbuchstaben-Problem: Sollte WHERE sequence_name = 'MY_SEQUENCE_NAME' sein; –

+0

@ammoQ Es ist jetzt korrigiert, danke. – jva

+0

Ich änderte den Tabellennamen zu "user_sequences" – Shawn

4

Ich mag außer Acht gelassen werden:

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; 
/
+0

Viel einfacher zu verwenden ERSTELLEN ODER ERSETZEN VON TRIGGER MyTriggerName BEVOR SIE INSERT auf MyTable ..... – Oscar

0
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; 
/

ODER

-- 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; 
/
Verwandte Themen