2009-04-28 20 views

cevap

19

sizinle başlamak isteyebilirsiniz max(trans_seq_no) + 1.

izle: Bir sayı ile bir diziyi oluştururken

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 

, size dizisine karşı seçmek ilk kez Oracle döneceğini hatırlamak zorunda atadığınız başlangıç ​​değeri. Eğer 'boşluksuz' olanı yapmaya çalışıyorsanız

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. 

, şiddetle bunu

1 olması gerektiği belirtilir ve 2. bunun için bir diziyi kullanmayın.

+0

+1, dizinin başlangıç ​​noktasındaki yakalama için. Ayrıca, CACHE parametresini 1'den başka bir şeye ayarlıyorsa, boşluklar konusunda endişelenmiyor. – DCookie

+2

Önbelleğin düşük olduğunu belirtecektim ama bu sorunun kapsamı dışındaydı. Şimdi kullanıcı boşluksuz rakamlar bekliyorsa, bir sırayla, başka şeyler geliyor. Rollback, bir diziyi 'azaltmaz';) –

+1

Hmm, altta kalın olan tavsiye, alternatif bir yaklaşım ve/veya bir açıklama çağrısında bulunur ... –

15

CREATE SEQUENCE ifadesinin içinde bir alt seçemezsiniz. Değeri önceden seçmeniz gerekecek. Eğer PL/SQL kullanabiliyorsa

+1

+1 güzel yakalamak .. – raksja

+0

Doğru - Ama Bunu otomatikleştirmek için basit bir alternatif var mı? –

33

, (EDIT: birleştirir Neil'in xlnt öneri sonraki daha yüksek bir değer başlatmak için): deneyin

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; 

başka nokta dikkate almak: 20'ye CACHE parametresini ayarlayarak, koşmak Veritabanı düşerse, sıranızda 19 değere kadar kaybetme riski. Veritabanı yeniden başlatıldığında CACHEd değerleri kaybolur. Sıralamaya sık sık isabet etmedikçe veya boşluklarla ilgili çok fazla şey umursamıyorsanız, bunu 1 olarak ayarlıyorum.

Son bir nit: CACHE ve INCREMENT BY için belirttiğiniz değerler varsayılanlardır . Onları bırakabilir ve aynı sonucu alabilirsiniz.

+0

"ORA-00905: ilk anahtar kelimesi için eksik anahtar kelime" yi alıyorum ... – ADTC

12

Aralığın ortasında, MAX değeri sadece taahhütlü değerlerinin maksimum değeri olacaktır. 1234'ü geri alabilir ve birisinin zaten 1235'i eklediğini ancak işlenmemiş olduğunu düşünmeniz gerekebilir. İşte

+1

+1. Bunların hepsi sadece DB'nin aynı anda kimsenin yazmamasını sağlamanız durumunda güvende. – sleske

25

Sadece iyi çalışır benim örnek var:

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

Bu harika çalışıyor! @ united-exression bu nasıl otomatik hale getirebilirsiniz. Kabul edilen cevap olmalı. Cevabın neden cevaplandırılmamış cevabı olduğunu bilmiyorum ... – ADTC

3

az kod ve simplier ile Ivan Laharnar dayanarak:

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

Güzel. Henüz bir satır yoksa, select ve execute arasında şu satırı eklerim: 'lastSeq is null ise lastSeq: = 0; sonu ise; ' –

+0

Teşekkürler, güzel bahşiş! – dmonti

+0

Evet iyi örnek, ama senaryonun dizilimi yeniden yarattığım için senaryolarımı yeniden oluşturuyor. –

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

Sadece kod cevaptan kaçının. Lütfen detaylandırın. – aloisdg

İlgili konular