Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Wie setze ich in Oracle 10g jedes Jahr automatisch den Wert einer Sequenz auf 0 zurück?

Sequenzen sind nicht wirklich darauf ausgelegt, zurückgesetzt zu werden. Es gibt jedoch Fälle, in denen das Zurücksetzen einer Sequenz wünschenswert ist, z. B. beim Einrichten von Testdaten oder beim Zusammenführen von Produktionsdaten zurück in eine Testumgebung. Diese Art von Aktivität ist nicht normalerweise in der Produktion.

WENN diese Art von Betrieb in Produktion genommen werden soll, muss sie gründlich getestet werden. (Was am meisten Anlass zur Sorge gibt, ist die Möglichkeit, dass der Reset-Vorgang versehentlich zur falschen Zeit durchgeführt wird, z. B. mitten im Jahr.

Das Löschen und Neuerstellen der Sequenz ist ein Ansatz. Als Operation ist es ziemlich einfach, was die SEQUENCE angeht:

    DROP SEQUENCE MY_SEQ;
    CREATE SEQUENCE MY_SEQ START WITH 1 INCREMENT BY 1 MINVALUE 0;

[BEARBEITEN] Wie Matthew Watson richtig betont, wird jede DDL-Anweisung (wie DROP, CREATE, ALTER) ein implizites Commit verursachen. [/BEARBEITEN]

Alle Berechtigungen, die der SEQUENCE gewährt wurden, werden jedoch gelöscht, sodass diese erneut gewährt werden müssen. Alle Objekte, die auf die Sequenz verweisen, werden ungültig gemacht. Um dies allgemeiner zu machen, müssten Sie Privilegien speichern (bevor Sie die Sequenz löschen) und sie dann erneut gewähren.

Ein zweiter Ansatz besteht darin, eine vorhandene SEQUENCE zu ÄNDERN, ohne sie zu löschen und neu zu erstellen. Das Zurücksetzen der Sequenz kann erreicht werden, indem der INCREMENT-Wert auf einen negativen Wert (die Differenz zwischen dem aktuellen Wert und 0) geändert wird und dann genau ein .NEXTVAL ausgeführt wird, um den aktuellen Wert auf 0 zu setzen, und dann INCREMENT wieder auf 1 geändert wird. Ich habe den gleichen Ansatz schon einmal verwendet (manuell in einer Testumgebung), um eine Sequenz auch auf einen größeren Wert zu setzen.

Damit dies richtig funktioniert, müssen Sie natürlich versichern Während dieser Vorgang ausgeführt wird, verweisen keine anderen Sitzungen auf die Sequenz. Ein zusätzliches .NEXTVAL im falschen Moment wird das Zurücksetzen vermasseln. (HINWEIS:Dies auf der Datenbankseite zu erreichen, wird schwierig sein, wenn sich die Anwendung als Eigentümer der Sequenz und nicht als separater Benutzer verbindet.)

Damit es jedes Jahr passiert, müssten Sie einen Job planen. Das Zurücksetzen der Sequenz muss mit dem Zurücksetzen des YYYY-Teils Ihrer Kennung koordiniert werden.

Hier ist ein Beispiel:

http://www.jaredstill.com/content/reset-sequence.html

[BEARBEITEN]

UNGETESTET Platzhalter für ein mögliches Design eines PL/SQL-Blocks zum Zurücksetzen der Sequenz

    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;
    /

HINWEISE:

  • Wie schütze ich die Sequenz am besten vor Zugriffen, während sie zurückgesetzt wird, umbenennen?
  • Mehrere Testfälle, die hier durchgearbeitet werden können.
  • Überprüfen Sie im ersten Durchgang die normativen Fälle einer positiven, aufsteigenden Inkrement-1-Folge.
  • Wäre ein besserer Ansatz darin, eine neue SEQUENCE zu erstellen, Berechtigungen hinzuzufügen, vorhandene und neue Sequenzen umzubenennen und dann Abhängigkeiten neu zu kompilieren?