Как я могу устранить ошибки уникальных ограничений?

Ниже мой код.

declare
    v1 tblsubject.subjectseq%type;
    v2 tblteam.teamname%type;
    cursor vcursor is
        select distinct t5.SUBJECTSEQ, t1.TEAMNAME
        from tblteam t1
                 inner join TBLCLASS t2 on t1.CLASSSEQ = t2.CLASSSEQ
                 inner join TBLOPENCOURSE T on T.OPENCOURSESEQ = t2.OPENCOURSESEQ
                 inner join TBLOPENSUBJECT T3 on T.OPENCOURSESEQ = T3.OPENCOURSESEQ
                 inner join TBLAVAILABLESUBJECT T4 on T4.AVAILABLESUBJECTSEQ = T3.AVAILABLESUBJECTSEQ
                 inner join TBLSUBJECT T5 on T5.SUBJECTSEQ = t4.SUBJECTSEQ;
begin
    open vcursor;
    loop
        fetch vcursor into v1, v2;
        insert into tblproject
        select rownum, t5.SUBJECTNAME || 'project', T3.SUBJECTEND, t1.TEAMSEQ
from tblteam t1
         inner join TBLCLASS t2 on t1.CLASSSEQ = t2.CLASSSEQ
         inner join TBLOPENCOURSE T on T.OPENCOURSESEQ = t2.OPENCOURSESEQ
         inner join TBLOPENSUBJECT T3 on T.OPENCOURSESEQ = T3.OPENCOURSESEQ
         inner join TBLAVAILABLESUBJECT T4 on T4.AVAILABLESUBJECTSEQ = T3.AVAILABLESUBJECTSEQ
         inner join TBLSUBJECT T5 on T5.SUBJECTSEQ = t4.SUBJECTSEQ
where (v1, v2) in (
    select distinct t5.SUBJECTSEQ, t1.TEAMNAME
    from tblteam t1
             inner join TBLCLASS t2 on t1.CLASSSEQ = t2.CLASSSEQ
             inner join TBLOPENCOURSE T on T.OPENCOURSESEQ = t2.OPENCOURSESEQ
             inner join TBLOPENSUBJECT T3 on T.OPENCOURSESEQ = T3.OPENCOURSESEQ
             inner join TBLAVAILABLESUBJECT T4 on T4.AVAILABLESUBJECTSEQ = T3.AVAILABLESUBJECTSEQ
             inner join TBLSUBJECT T5 on T5.SUBJECTSEQ = t4.SUBJECTSEQ);
        exit when vcursor%notfound;
        dbms_output.PUT_LINE(v1);
        dbms_output.PUT_LINE(v2);
    end loop;
end;

Структура таблицы для рассматриваемой 14-й строки:

create table TBLPROJECT
(
    PROJECTSEQ NUMBER not null
        constraint TBLPROJECT_PK
        primary key,
    PROJECTREGIST VARCHAR2(300),
    PROJECTSUBMITDATE DATE,
    TEAMSEQ NUMBER
)

Выполнить оператор PL / SQL

[2021-06-03 20:22:44] [23000][1]
[2021-06-03 20:22:44] ORA-00001: unique constraint (SIST2.TBLPROJECT_PK) violated
[2021-06-03 20:22:44] ORA-06512: at line 16
[2021-06-03 20:22:44] Position: 0

Появляется указанная выше ошибка.

У меня нет кода, нарушающего ограничение целостности, и я не знаю, как это исправить.

с уважением

Источник
  • 1
    Что ж, Oracle не согласен с вами в том, что ваш код нарушает ограничение целостности. Я не совсем понимаю, что вы пытаетесь сделать, но rownum первичного ключа с помощью rownum в цикле вряд ли сработает. Каждый запрос будет начинаться с rownum 1, поэтому, если insert пытается вставить строки в нескольких итерациях цикла, вы нарушите ограничение, пытаясь вставить несколько строк со значением первичного ключа 1. Обычно вы должны использовать последовательность для заполнения первичного ключа и выбора следующего nextval последовательности в операторе insert
Codelisting
за 2 против

Ваше условие выхода из цикла находится не в том месте; должен быть:

    loop
        fetch vcursor into v1, v2;
        exit when vcursor%notfound;
        insert into tblproject
        ...

В настоящий момент последняя успешная выборка вызывает вставку; затем вы снова выполняете выборку, которая больше не находит данных, но вы все равно вставляете на основе последних выбранных значений, которые будут дублироваться.

Вы, вероятно, хотитеdbms_output вызывает также и перед вставкой, так что вы можете хотя бы отладить значение, вызывающее сбой вставки.

Однако, используяrownum также похоже, что это приведет к дублированию, поскольку это будет повторять значения для каждой итерации цикла. Вы можете увидеть это в этой демонстрации скрипта db <> ; каждый раз по кругу вы получаете то же самоеrn значение (как псевдоним дляrownum ). Когда он пытается вставить это, вместо того, чтобы просто печатать значения, он пытается вставить две строки с одинаковым значением PK, что вызывает ошибку ограничения.

Это значение PK, возможно, следует взять из последовательности (или сделать его столбцом идентификации), но это зависит от того, почему вы делаете это сейчас так.

И для этого, вероятно, вообще не нужен PL / SQL; но переписывание в виде единственного оператора вставки выходит за рамки.

  • 0
    таблица пуста ... и выйти, когда ниже выборки, но она не решена
  • 0
    Какая таблица пуста - целевая таблица при запуске? Это не имеет значения, дублируются ли вставки в вашем коде. Как я и Джастин оба сказали, использование rownum к дублированию; во второй раз в цикле вы снова получите rownum начиная с 1, что сразу же будет дублированным PK.
Codelisting
Популярные категории
На заметку программисту