2012-03-07 20 views
7

Necesito reenviar un conjunto de secuencias con solo acceso DML. Debido a un error en un fragmento de código, se tomaron varios valores sin una secuencia, sino manualmente, por lo que ahora la secuencia está duplicando esos valores. Por lo tanto, me gustaría llevar la secuencia al valor máximo para que la próxima vez que se invoque nextval, se obtenga un valor superior al máximo. Tengo alrededor de 50 secuencias que cada una tiene que avanzar unos miles.Reenviar manualmente una secuencia - oracle sql

¿Es esto posible solo con acceso DML? Si es así, ¿cómo debo hacerlo?

Respuesta

8

Puede utilizar SQL dinámico para hacer esto. Por ejemplo, este bit de código seleccionará los siguientes 10,000 valores de cada una de una lista de secuencias.

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; 

Si tuviera la capacidad de emitir DDL contra la secuencia, se puede utilizar un enfoque similar para establecer el INCREMENT a 10.000, seleccione un valor de la secuencia, y establecer el INCREMENT de vuelta a 1 (o lo que sea Esto es ahora).

+0

Esto es brillante. Puedo calcular el número de bucles necesarios para cada secuencia al restar el siguiente valor de la secuencia del valor máximo de la columna relevante para hacer esto automáticamente. No me di cuenta de que sql tenía esa funcionalidad. ¡Gracias! – Jeremy

2

sólo puede

select seq.nextval from dual 

hasta que sea lo suficientemente grande ...

+0

Tengo alrededor de 50 secuencias que tienen que avanzar unos miles. – Jeremy

+0

¿se puede ejecutar PLSQL? – Randy

1

Para reiniciar la secuencia en un valor diferente, debe soltarlo y volver a crearlo.

Consulte los documentos de Oracle para ALTER SEQUENCEhere.

Y para CREATE SEQUENCEhere

Por lo tanto, no, yo no creo que sea posible con el acceso LMD, a menos que sólo se incrementa en varias ocasiones como Randy sugiere.

4

Debe determinar la diferencia entre el siguiente valor de la secuencia y el valor requerido. El valor requerido suele ser el valor máximo de una columna de clave principal (nombrele 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

Si usted tiene una tabla con al menos tantas filas como la cantidad que desea añadir a sus secuencias, el siguiente trabajo. Esto incrementa cada secuencia en la misma cantidad, lo que puede no ser adecuado para usted, pero es rápido y fácil sin requerir PL/SQL o la necesidad de colocar/volver a crear la secuencia. Lo uso todo el tiempo cuando quiero obtener secuencias del servidor de desarrollo antes de la producción.

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