User Tools

Site Tools


oracle:index

Oracle

Pues sí, inicio esta página dedicada a truquillos de oracle porque acabo de hacer uno que es lo que mi tío llamaría un “mirlo blanco”1): poner el “nextval” en un número de secuencia.

Poner el valor siguiente (nextval) en un número de secuencia

Si sois lo suficientemente osados para consultar la documentacion de Oracle, en concreto el apartado dedicado al comando ALTER SEQUENCE, vereis con desagrado que ¡oh desgracia! se puede cambiar de todo menos el valor actual.

Para más recochineo, el manual dice explicitamente:

To restart the sequence at a different number, you must drop and re-create it.

Vamos, que no se les ha olvidado: los muy… lo han hecho aposta. La gente ha ido dándole vueltas al coco y ha dado con una solución a este problema:

  • obtenemos el siguiente valor mediante un select … into X
  • ponemos que el incremento de la secuencia es -X
  • …y hacemos secuencia.nextval, con lo cual vuelve a cero
  • ponemos el incremento de la secuencia de nuevo en 1
  • y ya está, la secuencia inicializada

Yo le he dado una vuelta de tuerca a este asunto y he mejorado el script reset_seq que ponían en esta página: el mío permite inicializar la secuencia en cualquier número que establezcamos: es perfecto para volver al redil a esas secuencias que se han descoordinado con respecto a su tabla “amiga”.

Sin más, ahí va el script:

 
CREATE OR REPLACE PROCEDURE reset_seq( p_seq_name IN VARCHAR2, p_newnumber IN NUMBER )
IS
    l_nextval NUMBER;
    l_minus NUMBER;
    l_newnumber NUMBER;
BEGIN
    EXECUTE IMMEDIATE
    'select ' || p_seq_name || '.nextval from dual' INTO l_nextval;
 
    l_newnumber := p_newnumber - 1; 
    l_minus := l_nextval - l_newnumber;
 
    l_minus := l_minus * -1;
 
    --dbms_output.put_line( 'l_nextval: ' || l_nextval ); 
    --dbms_output.put_line( 'l_newnumber: ' || l_newnumber ); 
    --dbms_output.put_line( 'resultado minus: ' || l_minus ); 
 
    IF l_minus <> 0 THEN 
 
      EXECUTE IMMEDIATE
      'alter sequence ' || p_seq_name || ' increment by ' || l_minus ||
                                                            ' minvalue 0';
 
      EXECUTE IMMEDIATE
      'select ' || p_seq_name || '.nextval from dual' INTO l_nextval;
 
      EXECUTE IMMEDIATE
      'alter sequence ' || p_seq_name || ' increment by 1 minvalue 0';
 
    END IF; 
END;

Como veis, tampoco me he matado. Un consejo: si quisieramos ser puristas, no hay porqué suponer que las secuencias se autoincrementan en uno, podrían hacerlo en otro valor. Entonces habría que recuperar el valor de autoincremento antes de cambiarlo y luego restablecerlo por el que hemos almacenado. Pero bueno, con esto era suficiente para mi gestión.

Espero que os sirva.

1)
Como todo el mundo sabe, los mirlos son negros. De ahí que la expresión “mirlo blanco” se use para referirse a algo de extrema rareza
oracle/index.txt · Last modified: 2016/04/27 09:44 by rlunaro