SQL - Буферные вставки
Я создаю операторы вставки для заполнения моих таблиц. Они работают нормально, когда я их тестирую, однако, когда я начинаю буферизовать тот же код, который работал ранее, внезапно выдает ошибку (ORA-00001: ограничение уникальности нарушено). При исследовании проблемы кажется, что проблема возникает при попытке ввести дублирующую информацию в таблицу. Тем не менее, я всегда очищаю последовательности и повторно вводю их перед буферизацией, чтобы это не имело смысла. Вот пример того, что я пытаюсь запустить, и, как я уже сказал, код работает нормально:
SQL> INSERT INTO bill_tos_sr
2 (
3 bill_to_no,
4 bill_to_name,
5 bill_to_street,
6 bill_to_city,
7 bill_to_state,
8 bill_to_zip,
9 bill_to_phone
10 )
11 VALUES
12 (bill_tos_seq.NEXTVAL,
13 'Walmart',
14 '1000 Indiantown St',
15 'Ft Lauderdale',
16 'FL',
17 '33401',
18 '9438476698'
19 );
INSERT INTO bill_tos_sr
*
ERROR at line 1:
ORA-00001: unique constraint (MONPM16.BILL_TO_NO_PK) violated
2 ответа
Сброс последовательности (в этом случае удаление и повторное создание) не влияет на данные, которые уже существуют в таблице. Между последовательностью и таблицей нет реальной связи, кроме как через ваш код. (Вы можете использовать одну и ту же последовательность для нескольких таблиц, например). Это не будет правдой, если вы используете столбец идентификаторов в 12c+; но ты не в своем примере.
Итак, на самом деле вы сделали следующее:
create sequence bill_tos_seq;
insert into bill_tos_sr (bill_to_no, ...) values (bill_tos_seq.nextval, ...);
drop sequence bill_tos_seq;
create sequence bill_tos_seq;
insert into bill_tos_sr (bill_to_no, ...) values (bill_tos_seq.nextval, ...);
Если не указано иное, обе версии последовательности начнутся с 1, что означает, что обе ваши вставки будут пытаться создать строку с bill_to_no
установить в 1 - что нарушает ограничение.
Вам нужно удалить данные из таблицы, прежде чем пытаться заново их вставить. Если для начала было пусто, то вы можете просто обрезать или удалить (будьте осторожны, конечно!).
create sequence bill_tos_seq;
insert into bill_tos_sr (bill_to_no, ...) values (bill_tos_seq.nextval, ...);
drop sequence bill_tos_seq;
truncate table bill_tos_sr;
create sequence bill_tos_seq;
insert into bill_tos_sr (bill_to_no, ...) values (bill_tos_seq.nextval, ...);
Если у вас уже были данные до того, как вы начали, вам нужно выяснить, какие строки вы вставили в первый раз, и только удалить их.
Вы также могли бы проверить и повторить это с помощью отката:
create sequence bill_tos_seq;
insert into bill_tos_sr (bill_to_no, ...) values (bill_tos_seq.nextval, ...);
rollback;
drop sequence bill_tos_seq;
create sequence bill_tos_seq;
insert into bill_tos_sr (bill_to_no, ...) values (bill_tos_seq.nextval, ...);
Обратите внимание, что если вы это сделаете, это должно произойти до удаления / создания последовательности, потому что DDL фиксирует неявно; поэтому откат впоследствии не будет иметь никакого эффекта.
Возможно, вы откатились не в ту точку, или вы вообще не откатились и не осознали, что данные были зафиксированы по какой-то другой причине - возможно, вы вышли из SQL*Plus и не поняли, что это произойдет с помощью по умолчанию тоже. После того, как данные были зафиксированы, вы должны удалить их, прежде чем сможете их повторно вставить, иначе вы по-прежнему будете получать нарушения ограничений.
Однако это не имеет ничего общего с буферизацией вывода.
Я приду BILL_TO_NO_PK
является PK/ уникальным ограничением столбца BILL_TO_NO
,
При вставке вы предоставляете новые значения из последовательности bill_tos_seq.NEXTVAL
, Кажется, последовательность была перезапущена или данные были введены вручную в таблицу.
В любом случае значения последовательности сталкиваются с существующими данными в таблице.
Решение? Я бы нашел максимальное значение для столбца, а затем установить значение последовательности на единицу больше, чем это значение.