Sekvenser är inte riktigt designade för att återställas. Men det finns vissa fall där det är önskvärt att återställa en sekvens, till exempel när du ställer in testdata eller sammanfogar produktionsdata tillbaka till en testmiljö. Den här typen av aktivitet är inte görs normalt i produktionen.
OM denna typ av operation ska sättas i produktion måste den testas noggrant. (Det som orsakar mest oro är risken för att återställningsproceduren av misstag kan utföras vid fel tidpunkt, som i mitten av året.
Att släppa och återskapa sekvensen är ett tillvägagångssätt. Som operation är det ganska okomplicerat när det gäller SEKVENS:
DROP SEQUENCE MY_SEQ; CREATE SEQUENCE MY_SEQ START WITH 1 INCREMENT BY 1 MINVALUE 0;
[EDIT] Som Matthew Watson korrekt påpekar, kommer varje DDL-sats (som en DROP, CREATE, ALTER) att orsaka en implicit commit. [/EDIT]
Men alla privilegier som beviljas på SEQUENCE kommer att tas bort, så de kommer att behöva beviljas på nytt. Alla objekt som refererar till sekvensen blir ogiltiga. För att få detta mer generaliserat måste du spara privilegier (innan du släpper sekvensen) och sedan ge dem på nytt.
Ett andra tillvägagångssätt är att ÄNDRA en befintlig SEKVENS, utan att tappa och återskapa den. Återställning av sekvensen kan åstadkommas genom att ändra INCREMENT-värdet till ett negativt värde (skillnaden mellan det aktuella värdet och 0), och sedan göra exakt en .NEXTVAL för att ställa in det aktuella värdet till 0, och sedan ändra INCREMENT tillbaka till 1. Jag har använt samma tillvägagångssätt tidigare (manuellt, i en testmiljö), för att även ställa in en sekvens till ett högre värde.
För att detta ska fungera korrekt måste du naturligtvis försäkra inga andra sessioner refererar till sekvensen medan denna operation utförs. En extra .NEXTVAL vid fel ögonblick kommer att skruva upp återställningen. (OBS:att uppnå det på databassidan kommer att bli svårt, om applikationen ansluter som ägare av sekvensen, snarare än som en separat användare.)
För att det ska hända varje år måste du schemalägga ett jobb. Sekvensåterställningen måste koordineras med återställningen av YYYY-delen av din identifierare.
Här är ett exempel:
http://www.jaredstill.com/content/reset-sequence.html
[EDIT]
OTESTAD platshållare för en möjlig design av ett PL/SQL-block för att återställa sekvens
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; /
ANMÄRKNINGAR:
- hur man bäst skyddar sekvensen från åtkomst medan den återställs, BYT DAMN?
- Flera testfall att arbeta igenom här.
- Första pass, kontrollera normativa fall av positiv, stigande, steg 1 sekvens.
- skulle ett bättre tillvägagångssätt vara att skapa ny SEQUENCE, lägga till behörigheter, byta namn på befintliga och nya sekvenser och sedan kompilera om beroenden?