Вручную переслать последовательность - оракул sql - PullRequest
9 голосов
/ 08 марта 2012

Мне нужно переслать набор последовательностей только с доступом DML. Из-за ошибки в куске кода несколько значений были получены без последовательности, но вместо этого вручную, поэтому теперь последовательность дублирует эти значения. Итак, я хотел бы подтолкнуть последовательность к максимальному значению, чтобы при следующем вызове nextval она получала значение, превышающее максимальное. У меня есть около 50 последовательностей, каждая из которых должна пройти несколько тысяч вперед.

Возможно ли это только при доступе по DML? Если так, как я должен идти об этом?

Ответы [ 5 ]

10 голосов
/ 08 марта 2012

Вы можете использовать динамический SQL для этого.Например, этот бит кода выберет следующие 10 000 значений из каждого списка последовательностей.

DECLARE
  l_num INTEGER;
BEGIN
  FOR seq IN (select * 
                from all_sequences
                where sequence_name in (<<list of 50 sequences>>) 
                  and sequence_owner = <<owner of sequences>>)
  LOOP
    FOR i IN 1 .. 10000
    LOOP
      execute immediate 
         'select ' || seq.sequence_owner || '.' || seq.sequence_name || '.nextval from dual'
         into l_num;
    END LOOP;
  END LOOP;
END;

Если бы у вас была возможность выдавать DDL для последовательности, вы могли бы использовать аналогичный подход для установкиот INCREMENT до 10000, выберите одно значение из последовательности и установите INCREMENT обратно на 1 (или как там сейчас).

8 голосов
/ 04 февраля 2014

Вы должны определить разницу между следующим значением последовательности и требуемым значением. Обязательное значение обычно является максимальным значением столбца первичного ключа (назовем его ID).

DECLARE
    maxid NUMBER;
    maxseq NUMBER;
    temp NUMBER;  -- without this variable Oracle would skip to query the sequence
BEGIN
    SELECT MAX(ID) INTO maxid FROM MYTABLE;
    SELECT MYSEQ.NEXTVAL INTO maxseq FROM DUAL;
    FOR i IN maxseq .. maxid LOOP
        SELECT MYSEQ.NEXTVAL INTO temp FROM DUAL;
    END LOOP;
END;
/
2 голосов
/ 02 января 2015

Если ваша таблица содержит как минимум столько строк, сколько вы хотите добавить в свои последовательности, сработает следующее.Это увеличивает каждую последовательность на одну и ту же величину, что может вас не устраивать, но это быстро и просто, не требуя PL / SQL или необходимости удалять / заново создавать последовательность.Я использую его все время, когда хочу, чтобы последовательности серверов разработки опережали производство.

SELECT seq1.nextval, seq2.nextval, ..., seqN.nextval
  FROM very_large_table
 WHERE ROWNUM <= number_of_rows_to_add
2 голосов
/ 08 марта 2012

вы можете просто

select seq.nextval from dual 

пока он не станет достаточно большим ...

1 голос
/ 08 марта 2012

Чтобы перезапустить последовательность с другим значением, вам нужно отбросить и воссоздать ее.

См. Документы Oracle для ALTER SEQUENCE здесь .

А для CREATE SEQUENCE здесь

Итак, нет, я не думаю, что это возможно с доступом к DML, если только вы не увеличиваете несколько раз, как предлагает Рэнди.

...