Oracle
 sql >> база данни >  >> RDS >> Oracle

Как да нулирам автоматично стойността на последователност на 0 всяка година в Oracle 10g?

Последователностите всъщност не са предназначени да бъдат нулирани. Но има някои случаи, в които нулирането на последователност е желателно, например при настройване на тестови данни или сливане на производствени данни обратно в тестова среда. Този тип дейност не обикновено се прави в производството.

АКО този тип операция ще бъде пусната в производство, тя трябва да бъде щателно тествана. (Това, което предизвиква най-голямо безпокойство, е възможността процедурата за нулиране да бъде случайно извършена в неподходящ момент, например в средата на годината.

Отпадането и повторното създаване на последователността е един подход. Като операция, това е доста лесно, що се отнася до ПОСЛЕДОВАТЕЛНОСТТА:

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

[EDIT] Както Матю Уотсън правилно отбелязва, всеки DDL оператор (като DROP, CREATE, ALTER) ще предизвика имплицитно ангажиране. [/РЕДАКТИРАНЕ]

Но всички привилегии, предоставени на ПОСЛЕДОВАТЕЛНОСТТА, ще бъдат премахнати, така че ще трябва да бъдат предоставени отново. Всички обекти, които препращат към последователността, ще бъдат невалидни. За да направите това по-обобщено, ще трябва да запазите привилегии (преди да изпуснете последователността) и след това да ги предоставите отново.

Вторият подход е да ПРОМЕНИТЕ съществуваща ПОСЛЕДОВАТЕЛНОСТ, без да я изпускате и създавате отново. Нулирането на последователността може да бъде осъществено чрез промяна на стойността INCREMENT на отрицателна стойност (разликата между текущата стойност и 0) и след това направете точно един .NEXTVAL, за да зададете текущата стойност на 0, и след това промените INCREMENT обратно на 1. Използвал съм същия подход преди (ръчно, в тестова среда), за да задам поредица и на по-голяма стойност.

Разбира се, за да работи коректно, трябва да се застраховате никакви други сесии не препращат към последователността, докато се изпълнява тази операция. Допълнителен .NEXTVAL в грешния момент ще прецака нулирането. (ЗАБЕЛЕЖКА:постигането на това от страна на базата данни ще бъде трудно, ако приложението се свързва като собственик на последователността, а не като отделен потребител.)

За да се случва всяка година, трябва да планирате работа. Нулирането на последователността ще трябва да бъде координирано с нулирането на частта ГГГГ на вашия идентификатор.

Ето един пример:

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

[РЕДАКТИРАНЕ]

НЕТЕСТВАНО контейнер за един възможен дизайн на PL/SQL блок за нулиране на последователност

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

ЗАБЕЛЕЖКИ:

  • как най-добре да защитите последователността от достъп, докато се нулира, ПРЕИМЕНУВАТЕ?
  • Няколко тестови случая за работа тук.
  • Първо преминаване, проверете нормативните случаи на положителна, възходяща, нарастваща 1 последователност.
  • по-добър подход ли би бил да се създаде нова ПОСЛЕДОВАТЕЛНОСТ, да се добавят разрешения, да се преименуват съществуващи и нови поредици и след това да се компилират отново зависимости?


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle SQL - Как да получите отделни редове с помощта на аналитична функция RANK() или DENSE_RANK() или ROW_NUMBER()?

  2. Как да разделим по месеци и да групираме месеци в тримесечие

  3. Oracle SQL подреждане по проблеми с подзаявката!

  4. Функция LPAD() в Oracle

  5. Агрегиране на низове в Oracle:множество редове в една колона