web-dev-qa-db-de.com

Wie erstelle ich eine Oracle-Sequenz, die mit dem maximalen Wert aus einer Tabelle beginnt?

Der Versuch, eine Sequenz in Oracle zu erstellen, die mit dem Maximalwert aus einer bestimmten Tabelle beginnt. Warum funktioniert das nicht?

CREATE SEQUENCE transaction_sequence
  MINVALUE 0
  START WITH (SELECT MAX(trans_seq_no)
     FROM TRANSACTION_LOG) 
  INCREMENT BY 1
  CACHE 20;
42
Amar Patel

sie möchten vielleicht mit max(trans_seq_no) + 1. beginnen

sehen:

SQL> create table my_numbers(my_number number not null primary key);

Table created.

SQL> insert into my_numbers(select rownum from user_objects);

260 rows created.

SQL> select max(my_number) from my_numbers;

MAX(MY_NUMBER)
--------------
           260

SQL> create sequence my_number_sn start with 260;

Sequence created.

SQL> insert into my_numbers(my_number) values (my_number_sn.NEXTVAL);
insert into my_numbers(my_number) values (my_number_sn.NEXTVAL)
*
ERROR at line 1:
ORA-00001: unique constraint (NEIL.SYS_C00102439) violated

Wenn Sie eine Sequenz mit einer Nummer erstellen, müssen Sie daran denken, dass Oracle bei der ersten Auswahl der Sequenz den von Ihnen zugewiesenen Anfangswert zurückgibt.

SQL> drop sequence my_number_sn;

Sequence dropped.

SQL> create sequence my_number_sn start with 261;

Sequence created.

SQL>  insert into my_numbers(my_number) values (my_number_sn.NEXTVAL);

1 row created.

Wenn Sie versuchen, das "lückenlose" Ding zu tun, rate ich Ihnen dringend dazu 

Ich mache es nicht und # 2 benutze keine Sequenz dafür.

19
Neil Kodner

Wenn Sie PL/SQL verwenden können, versuchen Sie (EDIT: Enthält den Vorschlag von Neil zu xlnt, um mit dem nächst höheren Wert zu beginnen):

SELECT 'CREATE SEQUENCE transaction_sequence MINVALUE 0 START WITH '||MAX(trans_seq_no)+1||' INCREMENT BY 1 CACHE 20'
  INTO v_sql
  FROM transaction_log;

EXECUTE IMMEDIATE v_sql;

Ein weiterer zu berücksichtigender Punkt: Wenn Sie den Parameter CACHE auf 20 setzen, besteht das Risiko, dass Sie bis zu 19 Werte in Ihrer Sequenz verlieren, wenn die Datenbank ausfällt. CACHEd-Werte gehen bei Datenbankneustarts verloren. Wenn Sie die Sequenz nicht sehr oft treffen oder sich nicht so sehr auf Lücken konzentrieren, würde ich sie auf 1 setzen.

Ein letzter Schritt: Die Werte, die Sie für CACHE und INCREMENT BY angegeben haben, sind die Standardwerte. Sie können sie ausschalten und das gleiche Ergebnis erzielen.

36
DCookie

Hier habe ich mein Beispiel, das gut funktioniert:

declare
 ex number;
begin
  select MAX(MAX_FK_ID)  + 1 into ex from TABLE;
  If ex > 0 then
    begin
            execute immediate 'DROP SEQUENCE SQ_NAME';
      exception when others then
        null;
    end;
    execute immediate 'CREATE SEQUENCE SQ_NAME INCREMENT BY 1 START WITH ' || ex || ' NOCYCLE CACHE 20 NOORDER';
  end if;
end;
28

Sie können keine Unterauswahl in einer CREATE SEQUENCE-Anweisung verwenden. Sie müssen den Wert vorher auswählen.

16
Chad Birch

In der Mitte ist der MAX-Wert nur der Höchstwert der zugesagten Werte. Möglicherweise wird 1234 zurückgegeben, und Sie müssen möglicherweise berücksichtigen, dass jemand bereits 1235 eingefügt hat, jedoch noch nicht festgeschrieben hat.

12
Gary Myers

Basierend auf Ivan Laharnar mit weniger Code und einfacher:

declare
    lastSeq number;
begin
    SELECT MAX(ID) + 1 INTO lastSeq FROM <TABLE_NAME>;
    if lastSeq IS NULL then lastSeq := 1; end if;
    execute immediate 'CREATE SEQUENCE <SEQUENCE_NAME> INCREMENT BY 1 START WITH ' || lastSeq || ' MAXVALUE 999999999 MINVALUE 1 NOCACHE';
end;
4
dmonti
DECLARE
    v_max NUMBER;
BEGIN
    SELECT (NVL (MAX (<COLUMN_NAME>), 0) + 1) INTO v_max FROM <TABLE_NAME>;
    EXECUTE IMMEDIATE 'CREATE SEQUENCE <SEQUENCE_NAME> INCREMENT BY 1 START WITH ' || v_max || ' NOCYCLE CACHE 20 NOORDER';
END;
0
evandertino