Как создать последовательность Oracle, начиная с максимального значения из таблицы? - PullRequest
42 голосов
/ 28 апреля 2009

Попытка создать последовательность в Oracle, которая начинается с максимального значения из определенной таблицы. Почему это не работает?

CREATE SEQUENCE transaction_sequence
  MINVALUE 0
  START WITH (SELECT MAX(trans_seq_no)
     FROM TRANSACTION_LOG) 
  INCREMENT BY 1
  CACHE 20;

Ответы [ 7 ]

36 голосов
/ 28 апреля 2009

Если вы можете использовать PL / SQL, попробуйте (РЕДАКТИРОВАТЬ: Включает предложение Нила xlnt начать со следующего более высокого значения):

SELECT 'CREATE SEQUENCE transaction_sequence MINVALUE 0 START WITH '||MAX(trans_seq_no)+1||' INCREMENT BY 1 CACHE 20'
  INTO v_sql
  FROM transaction_log;

EXECUTE IMMEDIATE v_sql;

Еще один момент, на который следует обратить внимание: установив для параметра CACHE значение 20, вы рискуете потерять до 19 значений в последовательности, если база данных выйдет из строя. Значения CACHEd теряются при перезапуске базы данных. Если вы не выполняете последовательность очень часто или вас не волнуют пропуски, я установил бы ее на 1.

Один последний нит: значения, которые вы указали для CACHE и INCREMENT BY, являются значениями по умолчанию. Вы можете оставить их и получить тот же результат.

29 голосов
/ 29 мая 2013

Вот мой пример, который прекрасно работает:

declare
 ex number;
begin
  select MAX(MAX_FK_ID)  + 1 into ex from TABLE;
  If ex > 0 then
    begin
            execute immediate 'DROP SEQUENCE SQ_NAME';
      exception when others then
        null;
    end;
    execute immediate 'CREATE SEQUENCE SQ_NAME INCREMENT BY 1 START WITH ' || ex || ' NOCYCLE CACHE 20 NOORDER';
  end if;
end;
19 голосов
/ 28 апреля 2009

вы можете начать с max(trans_seq_no) + 1.

часы:

SQL> create table my_numbers(my_number number not null primary key);

Table created.

SQL> insert into my_numbers(select rownum from user_objects);

260 rows created.

SQL> select max(my_number) from my_numbers;

MAX(MY_NUMBER)
--------------
           260

SQL> create sequence my_number_sn start with 260;

Sequence created.

SQL> insert into my_numbers(my_number) values (my_number_sn.NEXTVAL);
insert into my_numbers(my_number) values (my_number_sn.NEXTVAL)
*
ERROR at line 1:
ORA-00001: unique constraint (NEIL.SYS_C00102439) violated

Когда вы создаете последовательность с номером, вы должны помнить, что при первом выборе для последовательности Oracle вернет начальное значение, которое вы ей присвоили.

SQL> drop sequence my_number_sn;

Sequence dropped.

SQL> create sequence my_number_sn start with 261;

Sequence created.

SQL>  insert into my_numbers(my_number) values (my_number_sn.NEXTVAL);

1 row created.

Если вы пытаетесь сделать «без промежутков», я настоятельно советую вам

1 не делает этого, а # 2 не использует последовательность для него.

16 голосов
/ 28 апреля 2009

Вы не можете использовать подвыбор внутри оператора CREATE SEQUENCE. Вам нужно будет заранее выбрать значение.

12 голосов
/ 29 апреля 2009

Пометьте в середине, значение MAX будет максимальным только из зафиксированных значений. Он может вернуть 1234, и вам может потребоваться учесть, что кто-то уже вставил 1235, но не зафиксировал.

4 голосов
/ 13 июля 2017

На основе Ивана Лахарнара с меньшим количеством кода и проще:

declare
    lastSeq number;
begin
    SELECT MAX(ID) + 1 INTO lastSeq FROM <TABLE_NAME>;
    if lastSeq IS NULL then lastSeq := 1; end if;
    execute immediate 'CREATE SEQUENCE <SEQUENCE_NAME> INCREMENT BY 1 START WITH ' || lastSeq || ' MAXVALUE 999999999 MINVALUE 1 NOCACHE';
end;
0 голосов
/ 17 ноября 2017
DECLARE
    v_max NUMBER;
BEGIN
    SELECT (NVL (MAX (<COLUMN_NAME>), 0) + 1) INTO v_max FROM <TABLE_NAME>;
    EXECUTE IMMEDIATE 'CREATE SEQUENCE <SEQUENCE_NAME> INCREMENT BY 1 START WITH ' || v_max || ' NOCYCLE CACHE 20 NOORDER';
END;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...