2012-03-07 20 views
7

Muszę przesłać zestaw sekwencji z dostępem tylko DML. Z powodu błędu w kodzie pobrano kilka wartości bez sekwencji, ale zamiast tego ręcznie, więc teraz sekwencja powtarza te wartości. Tak więc chciałbym przesunąć sekwencję do maksymalnej wartości, aby przy następnym wywołaniu nextval, dawała wartość wyższą niż maksymalna. Mam około 50 sekwencji, z których każda musi przejść kilka tysięcy do przodu.Ręczne przekazywanie sekwencji - sql oracle

Czy jest to możliwe tylko z dostępem DML? Jeśli tak, jak mam się tym zająć?

Odpowiedz

8

Można użyć dynamicznego SQL, aby to zrobić. Na przykład ten fragment kodu wybierze kolejne 10 000 wartości z każdej listy sekwencji.

DECLARE 
    l_num INTEGER; 
BEGIN 
    FOR seq IN (select * 
       from all_sequences 
       where sequence_name in (<<list of 50 sequences>>) 
        and sequence_owner = <<owner of sequences>>) 
    LOOP 
    FOR i IN 1 .. 10000 
    LOOP 
     execute immediate 
     'select ' || seq.sequence_owner || '.' || seq.sequence_name || '.nextval from dual' 
     into l_num; 
    END LOOP; 
    END LOOP; 
END; 

Gdybyś miał możliwość emitowania DDL przeciwko sekwencji, można użyć podobnego podejścia do ustaw INCREMENT do 10000, wybierz jedną wartość z sekwencji i ustaw INCREMENT z powrotem w dół do 1 (lub cokolwiek to jest teraz).

+0

To jest genialne. Potrafię obliczyć liczbę pętli potrzebnych dla każdej sekwencji, odejmując kolejną wartość sekwencji od wartości maksymalnej odpowiedniej kolumny, aby zrobić to automatycznie. Nie zdawałem sobie sprawy, że sql ma taką funkcjonalność. Dziękuję Ci! – Jeremy

2

można po prostu

select seq.nextval from dual 

aż będzie wystarczająco duży ...

+0

Mam około 50 sekwencji, z których każda musi przejść kilka tysięcy do przodu. – Jeremy

+0

czy możesz uruchomić PLSQL? – Randy

1

Aby ponownie uruchomić sekwencję o innej wartości, należy ją upuścić i ponownie utworzyć.

Zobacz dokumentację Oracle dla ALTER SEQUENCEhere.

I CREATE SEQUENCEhere

Tak, nie nie sądzę, że to możliwe z dostępem DML, chyba że po prostu zwiększyć wielokrotnie jak Randy sugeruje.

4

Należy określić różnicę między następną wartością sekwencji a wymaganą wartością. Wymagana wartość jest zazwyczaj maksymalną wartością kolumny klucza podstawowego (nazwijmy ją ID).

DECLARE 
    maxid NUMBER; 
    maxseq NUMBER; 
    temp NUMBER; -- without this variable Oracle would skip to query the sequence 
BEGIN 
    SELECT MAX(ID) INTO maxid FROM MYTABLE; 
    SELECT MYSEQ.NEXTVAL INTO maxseq FROM DUAL; 
    FOR i IN maxseq .. maxid LOOP 
     SELECT MYSEQ.NEXTVAL INTO temp FROM DUAL; 
    END LOOP; 
END; 
/
1

Jeśli masz tabelę z co najmniej taką samą liczbą rzędów, jaką chcesz dodać do swoich sekwencji, poniższe czynności będą działać. Powoduje to zwiększenie każdej sekwencji o tę samą wartość, która może nie odpowiadać tobie, ale jest szybka i łatwa, bez konieczności korzystania z PL/SQL lub konieczności upuszczenia/ponownego utworzenia sekwencji. Używam go przez cały czas, gdy chcę uzyskać sekwencje serwera rozwoju przed produkcją.

SELECT seq1.nextval, seq2.nextval, ..., seqN.nextval 
    FROM very_large_table 
WHERE ROWNUM <= number_of_rows_to_add