Ниже мой код.
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
Появляется указанная выше ошибка.
У меня нет кода, нарушающего ограничение целостности, и я не знаю, как это исправить.
с уважением
Ваше условие выхода из цикла находится не в том месте; должен быть:
loop
fetch vcursor into v1, v2;
exit when vcursor%notfound;
insert into tblproject
...
В настоящий момент последняя успешная выборка вызывает вставку; затем вы снова выполняете выборку, которая больше не находит данных, но вы все равно вставляете на основе последних выбранных значений, которые будут дублироваться.
Вы, вероятно, хотитеdbms_output
вызывает также и перед вставкой, так что вы можете хотя бы отладить значение, вызывающее сбой вставки.
Однако, используяrownum
также похоже, что это приведет к дублированию, поскольку это будет повторять значения для каждой итерации цикла. Вы можете увидеть это в этой демонстрации скрипта db <> ; каждый раз по кругу вы получаете то же самоеrn
значение (как псевдоним дляrownum
). Когда он пытается вставить это, вместо того, чтобы просто печатать значения, он пытается вставить две строки с одинаковым значением PK, что вызывает ошибку ограничения.
Это значение PK, возможно, следует взять из последовательности (или сделать его столбцом идентификации), но это зависит от того, почему вы делаете это сейчас так.
И для этого, вероятно, вообще не нужен PL / SQL; но переписывание в виде единственного оператора вставки выходит за рамки.
rownum
к дублированию; во второй раз в цикле вы снова получите rownum
начиная с 1, что сразу же будет дублированным PK.
rownum
первичного ключа с помощью rownum в цикле вряд ли сработает. Каждый запрос будет начинаться сrownum
1, поэтому, еслиinsert
пытается вставить строки в нескольких итерациях цикла, вы нарушите ограничение, пытаясь вставить несколько строк со значением первичного ключа 1. Обычно вы должны использовать последовательность для заполнения первичного ключа и выбора следующегоnextval
последовательности в оператореinsert
Justin Cave