Q: сбросить последовательность, помочь вокруг понимания - PullRequest
0 голосов
/ 15 декабря 2018

Я не понимаю, почему в этом коде есть оператор выбора и почему он имеет вдвое больший оператор последовательности для увеличения на

Я нашел этот код на сайте asktom

CREATE OR REPLACE 
PACKAGE pkg_seq AS
      PROCEDURE alterSequenceLast(
          sequenceName IN VARCHAR2,
          inc in integer);
END;
/

    CREATE OR REPLACE
PACKAGE BODY pkg_asktom AS
    PROCEDURE alterSequenceLast(
        sequenceName IN VARCHAR2,
        inc in integer)
    is
        stmt VARCHAR2(2000);
        l_n  number;
    begin
        BEGIN
            -- alter increment to inc
        stmt := 'ALTER SEQUENCE ' ||  sequenceName ||' INCREMENT BY ' ||inc;
            dbms_output.put_line('Executing ''' || stmt || '''');
            EXECUTE IMMEDIATE stmt;
            -- read the next value
            stmt := 'SELECT ' || sequenceName || '.NEXTVAL FROM DUAL';
            dbms_output.put_line('Executing ''' || stmt || '''');
            EXECUTE IMMEDIATE stmt into l_n;
            -- alter increment to 1
            stmt := 'ALTER SEQUENCE ' ||  sequenceName ||' INCREMENT BY 1';
            dbms_output.put_line('Executing ''' || stmt || '''');
            EXECUTE IMMEDIATE stmt;
        END;
    end alterSequenceLast;
END;
/

После исполнения я получаю это

SQL>  exec pkg_seq.alterSequenceLast('acc_seq',1);
Executing 'ALTER SEQUENCE acc_seq INCREMENT BY 1'
Executing 'SELECT acc_seq.NEXTVAL FROM DUAL'
Executing 'ALTER SEQUENCE acc_seq INCREMENT BY 1'

Я бы сделал это так, я бы вернул последовательность в начало.

CREATE OR REPLACE 
PACKAGE pkg_seq AS
      PROCEDURE alterSequenceLast(
          sequenceName IN VARCHAR2,
          inc in integer);
END;
/

    CREATE OR REPLACE
PACKAGE BODY pkg_seq AS
    PROCEDURE alterSequenceLast(
        sequenceName IN VARCHAR2,
        inc in integer)
    is
        stmt VARCHAR2(2000);
        l_n  number;
    begin
        BEGIN
stmt := 'ALTER SEQUENCE ' ||  sequenceName ||' restart start with ' ||inc;
         dbms_output.put_line('Executing ''' || stmt || '''');
         EXECUTE IMMEDIATE stmt;
         -- alter increment to 1
         stmt := 'ALTER SEQUENCE ' ||  sequenceName ||' INCREMENT BY 1';
            dbms_output.put_line('Executing ''' || stmt || '''');
            EXECUTE IMMEDIATE stmt;
        END;
    end alterSequenceLast;
END;
/

Так продвигается, Петар.

1 Ответ

0 голосов
/ 15 декабря 2018

Этот код предназначен для установки последовательности, начинающейся с нового значения.

Например, предположим, что у нас есть таблица, идентификатор которой обычно генерируется последовательностью our_seq, но по какой-то причине мы загрузили 10000 записей без использования последовательности.Что произойдет, если мы вставим новую запись?В текущем состоянии our_seq.nextval сгенерирует идентификатор, который конфликтует с ключом массовой загрузки записи.

Итак, нам нужно отрегулировать значение последовательности.Один из способов сделать это - выбрать nextval десять тысяч раз.Или мы можем

  1. изменить последовательность для увеличения на 10000
  2. выбрать nextval для последовательности один раз
  3. изменить последовательность для увеличения на 1 еще раз

Пакет Tom Kyte - это способ автоматизации второго подхода.Лично я бы расценил это как интересный сувенир.Если вам нужно выполнять эту операцию достаточно часто, чтобы автоматизировать ее, вам, вероятно, следует пересмотреть свои методы загрузки данных.


может [мы] увеличить последовательность на 10001 без выбора оператора?

Нет.Единственный поддерживаемый способ сделать это - удалить последовательность и заново создать ее с требуемым началом со значением.Удаление объекта более сложное из-за грантов, недействительности кода и т. Д.

Предположим, что вас интересует последовательность, скажем, текущее значение = 10001, и вы хотите сбросить ее, чтобы она начиналась с 1, и вы снова передали быотрицательный прирост -10001.Будьте осторожны, вы не уменьшаете его после minvalue (по умолчанию 1);база данных не будет вас предупреждать или бросать, пока вы не введете nextval, и в этот момент она сообщит вам:

ORA-08004: sequence OUR_SEQ.NEXTVAL goes below MINVALUE and cannot be instantiated  
...