Las secuencias no están realmente diseñadas para reiniciarse. Pero hay algunos casos en los que es deseable reiniciar una secuencia, por ejemplo, al configurar los datos de prueba o al fusionar los datos de producción en un entorno de prueba. Este tipo de actividad es no normalmente en producción.
SI este tipo de operación se va a poner en producción, necesita una prueba minuciosa. (Lo que más preocupa es la posibilidad de que el procedimiento de reinicio se realice accidentalmente en el momento equivocado, como a mediados de año.
La eliminación y recreación de la secuencia es un enfoque. Como operación, es bastante sencillo en cuanto a la secuencia va:
DROP SEQUENCE MY_SEQ;
CREATE SEQUENCE MY_SEQ START WITH 1 INCREMENT BY 1 MINVALUE 0;
[EDIT] como Matthew Watson señala correctamente, cada sentencia DDL (tales como DROP, CREATE, ALTER) hará que cometa un implícito [/ EDIT]
.
Pero, cualquier privilegio otorgado en la SECUENCIA se eliminará, por lo que deberá volver a otorgarse. Cualquier objeto que se refiera ya que la secuencia será invalidada. Para hacer esto más general, necesitaría guardar privilegios (antes de descartar la secuencia) y luego volver a otorgarlos.
Un segundo enfoque consiste en ALTERAR una SECUENCIA existente, sin soltarla y volverla a crear. Restablecer la secuencia se puede lograr cambiando el valor de INCREMENTO a un valor negativo (la diferencia entre el valor actual y 0), y luego hacer exactamente un .NEXTVAL para establecer el valor actual a 0, y luego cambiar el INCREMENT de nuevo a 1. He usado este mismo enfoque antes (manualmente, en un entorno de prueba), para establecer una secuencia a un valor mayor también.
Por supuesto, para que esto funcione correctamente, necesita asegurar ninguna otra sesión hace referencia a la secuencia mientras se realiza esta operación. Un .NEXTVAL adicional en el momento incorrecto arruinará el reinicio.(NOTA: lograr eso en el lado de la base de datos va a ser difícil, si la aplicación se conecta como el propietario de la secuencia, en lugar de como un usuario separado.)
Para que suceda todos los años, necesitaría para programar un trabajo. El reinicio de la secuencia tendrá que coordinarse con el restablecimiento de la parte YYYY de su identificador.
Aquí está un ejemplo:
http://www.jaredstill.com/content/reset-sequence.html
[EDIT]
sin probar marcador de posición para un posible diseño de un bloque PL/SQL para restablecer secuencia
declare
pragma autonomous_transaction;
ln_increment number;
ln_curr_val number;
ln_reset_increment number;
ln_reset_val number;
begin
-- save the current INCREMENT value for the sequence
select increment_by
into ln_increment
from user_sequences
where sequence_name = 'MY_SEQ';
-- determine the increment value required to reset the sequence
-- from the next fetched value to 0
select -1 - MY_SEQ.nextval into ln_reset_increment from dual;
-- fetch the next value (to make it the current value)
select MY_SEQ.nextval into ln_curr from dual;
-- change the increment value of the sequence to
EXECUTE IMMEDIATE 'alter sequence MY_SEQ increment by '
|| ln_reset_increment ||' minvalue 0';
-- advance the sequence to set it to 0
select MY_SEQ.nextval into ln_reset_val from dual;
-- set increment back to the previous(ly saved) value
EXECUTE IMMEDIATE 'alter sequence MY_SEQ increment by '
|| ln_increment ;
end;
/
NOTAS:
- cómo proteger mejor la secuencia de acceso mientras se está restableciendo, ¿RENOMBRAR?
- Varias cajas de prueba para trabajar aquí.
- En primer paso, verifique los casos normativos de secuencia ascendente, incremental 1 positiva.
- ¿sería un mejor enfoque crear una nueva SECUENCIA, agregar permisos, renombrar secuencias existentes y nuevas, y luego volver a compilar dependencias?
CUIDADO !! Hacer DML implicará un commit implicado. Si necesita deshacer su transacción, no podrá hacerlo después de ejecutar esto. –
Interesante. Pero como buena práctica, tiendo a tener mis secuencias locales para el esquema al que pertenecen, con lo que quiero decir que solo se usan en triggers/functions/procedures/packages en el mismo esquema. Por lo tanto, no tengo problemas relacionados con permisos, y la solución DROP/CREATE funciona bien. Si necesito un valor de secuencia fuera del esquema, siempre puedo usar una función/procedimiento personalizado. Además, esto es portátil (concedido, esto es inútil la mayor parte del tiempo). – Mac
corrección: DDL realiza una confirmación, DML no confirma por sí mismo.(y ALTER SEQUENCE es DDL, entonces sí, este es un problema aquí si alguien intenta usar esto como parte de su código de transacción normal) –