2012-03-07 20 views
7

Devo inoltrare una serie di sequenze con solo accesso DML. A causa di un bug in un pezzo di codice, diversi valori sono stati acquisiti senza una sequenza, ma invece manualmente, quindi ora la sequenza duplica quei valori. Quindi, vorrei spingere la sequenza al valore massimo in modo che la prossima volta che viene chiamato nextval, dia un valore superiore al massimo. Ho circa 50 sequenze che ognuna deve fare qualche migliaio in avanti.Inoltrare manualmente una sequenza - oracle sql

Ciò è possibile solo con accesso DML? Se è così, come dovrei farlo?

risposta

8

È possibile utilizzare SQL dinamico per fare questo. Ad esempio, questo bit di codice selezionerà i successivi 10.000 valori da ciascuno di un elenco di sequenze.

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; 

Se avete avuto la possibilità di emettere DDL contro la sequenza, è possibile utilizzare un approccio simile per impostare il INCREMENT a 10.000, selezionare un valore dalla sequenza, e impostare il INCREMENT giù a 1 (o qualsiasi altra cosa è adesso).

+0

Questo è geniale. Posso calcolare il numero di cicli necessari per ciascuna sequenza sottraendo il valore successivo della sequenza dal valore massimo della colonna pertinente per farlo automaticamente. Non mi rendevo conto che SQL aveva tale funzionalità. Grazie! – Jeremy

2

si può solo

select seq.nextval from dual 

fino a quando non è abbastanza grande ...

+0

Ho circa 50 sequenze che ognuna deve fare qualche migliaio in avanti. – Jeremy

+0

puoi eseguire PLSQL? – Randy

1

Per riavviare la sequenza con un valore diverso è necessario rilasciarla e ricrearla.

Vedere i documenti Oracle per ALTER SEQUENCEhere.

E per CREATE SEQUENCEhere

Quindi, no, non credo che sia possibile con accesso DML, a meno che non solo incrementa ripetutamente come suggerisce Randy.

4

È necessario determinare la differenza tra il valore successivo della sequenza e il valore richiesto. Il valore richiesto è in genere il valore massimo di una colonna chiave primaria (chiamiamolo 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

Se si dispone di un tavolo con almeno tante righe come la quantità che si desidera aggiungere ai sequenze, di seguito funzionerà. Questo incrementa ogni sequenza della stessa quantità, che potrebbe non essere adatta a te, ma è semplice e veloce senza richiedere PL/SQL o la necessità di eliminare/ricreare la sequenza. Lo uso sempre quando voglio ottenere sequenze di server di sviluppo prima della produzione.

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