powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / исключения forall при каскадном удалении через констрейнты
14 сообщений из 14, страница 1 из 1
исключения forall при каскадном удалении через констрейнты
    #39258827
receiver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вижу в чужой системе "заглавную" таблицу и иерархию подчиненных таблиц. До пятого уровня включительно.
Для удаления старых записей, разработчик понавтыкал во все таблицы всех уровней ID "заглавной" таблицы. Поддерживает внешними ключами и индексами.
Удаляет через forall

Код: plaintext
1.
2.
FORALL vloop in brec.FIRST .. brec.LAST SAVE EXCEPTIONS
   DELETE FROM KSA$TA_MAIN_TABLE WHERE rowid = brec(vloop);

Ошибки обрабатываются через SQL%BULK_EXCEPTIONS и записываются в лог. На выходе имею записи типа:
---
Код: plaintext
1.
2.
Oracle error is ORA-02292: integrity constraint (.) violated - child record found
Error 1 occurred during bulk deleting Movement-Data. Iteration 889
---

Могу ли я понять, какая запись и в какой таблице, при этом каскадном удалении была причиной ошибки?
...
Рейтинг: 0 / 0
исключения forall при каскадном удалении через констрейнты
    #39258832
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
receiverМогу ли я понять, какая запись и в какой таблице, при этом каскадном удалении была причиной ошибки?Нет. При SAVE EXCEPTIONS есть только код ошибки. Вывод - отказаться от притянутого за уши FORALL.
...
Рейтинг: 0 / 0
исключения forall при каскадном удалении через констрейнты
    #39258836
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ElicreceiverМогу ли я понять, какая запись и в какой таблице, при этом каскадном удалении была причиной ошибки?Нет. При SAVE EXCEPTIONS есть только код ошибки. Вывод - отказаться от притянутого за уши FORALL.
%BULK_EXCEPTIONS(i).ERROR_INDEX - не?
...
Рейтинг: 0 / 0
исключения forall при каскадном удалении через констрейнты
    #39258853
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymousElicreceiverМогу ли я понять, какая запись и в какой таблице, при этом каскадном удалении была причиной ошибки?Нет. При SAVE EXCEPTIONS есть только код ошибки. Вывод - отказаться от притянутого за уши FORALL.%BULK_EXCEPTIONS(i).ERROR_INDEX - не?Подумай сам.
...
Рейтинг: 0 / 0
исключения forall при каскадном удалении через констрейнты
    #39258886
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elicandrey_anonymousпропущено...
%BULK_EXCEPTIONS(i).ERROR_INDEX - не?Подумай сам.

Подумал. Вроде все работает как заповедано.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
create table dropme_parent(id primary key) as select rownum from dual connect by level < 10;
create table dropme_child(ref_id) as select 2*(1+mod(rownum,3)) from dual connect by level < 10;
alter table dropme_child add constraint dropme_fk foreign key(ref_id) references dropme_parent(id);

set serveroutput on

declare type ltt is table of rowid index by binary_integer;
  lt ltt;
  dml_error exception;
  pragma exception_init(dml_error, -24381);
  l_err_cnt number;
begin
  select rowid bulk collect into lt
    from dropme_parent
   where id < 5;
  forall i in 1..lt.count save exceptions
    delete dropme_parent where rowid = lt(i);
exception
  when dml_error then
    l_err_cnt := sql%bulk_exceptions.count;
    for i in 1..l_err_cnt loop
      dbms_output.put_line('rowid="'||lt(sql%bulk_exceptions(i).error_INDEX)||'", error= -'||sql%bulk_exceptions(i).error_code
      );
    end loop;
end;
/
----------------------------

Table created
Table created
Table altered

rowid="AAA+huAABAAAaBbAAB", error= -2292
rowid="AAA+huAABAAAaBbAAD", error= -2292
...
Рейтинг: 0 / 0
исключения forall при каскадном удалении через констрейнты
    #39258910
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymousПодумал.Недостаточно. Вопрос был не в том, какой папа не удалился, а в том, какой из многочисленных детей этому помешал.
...
Рейтинг: 0 / 0
исключения forall при каскадном удалении через констрейнты
    #39258915
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elicandrey_anonymousПодумал.Недостаточно. Вопрос был не в том, какой папа не удалился, а в том, какой из многочисленных детей этому помешал.
Ну от кого-кого, а от тебя не ожидал - словарем и dbms_% пользоваться ты точно умеешь :)
В конкретном сценарии ТС задача решается, причем даже не очень сложно.
В более общем случае - сложнее, да.
...
Рейтинг: 0 / 0
исключения forall при каскадном удалении через констрейнты
    #39258923
ora601
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
receiverМогу ли я понять, какая запись и в какой таблице, при этом каскадном удалении была причиной ошибки?

Не проще ли cascade поставить ?
...
Рейтинг: 0 / 0
исключения forall при каскадном удалении через констрейнты
    #39258951
Фотография --Eugene--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ora601Не проще ли cascade поставить ?а если ТС не хочет, собственно, удалять при имеющихся зависимостях, а хочет лишь знать чё-каво
...
Рейтинг: 0 / 0
исключения forall при каскадном удалении через констрейнты
    #39258956
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymousНу от кого-кого, а от тебя не ожидал - словарем и dbms_% пользоваться ты точно умеешь :)


ROWID то папaшкин. И что тeперь искать всех детей лейтенанта Шмидта?

SY.
...
Рейтинг: 0 / 0
исключения forall при каскадном удалении через констрейнты
    #39258967
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymousНу от кого-кого, а от тебя не ожидал - словарем и dbms_% пользоваться ты точно умеешь :)Аналогично. Неприятно удивлён. Спишу на отсутствие практического опыта. Ещё раз
ElicПри SAVE EXCEPTIONS есть только код ошибки.Как следствие - нет параметров текста ошибки.
...
Рейтинг: 0 / 0
исключения forall при каскадном удалении через констрейнты
    #39258986
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SYROWID то папaшкин. И что тeперь искать всех детей лейтенанта Шмидта?
SY.
Таки да, сгенерировать по словарю запрос и искать.
Благо это не особо сложно в частном конкретном случае и не хлопотно по ресурсам при индексированных fk.
В общем случае - задача довольно сложная, не спорю.
...
Рейтинг: 0 / 0
исключения forall при каскадном удалении через констрейнты
    #39259028
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymousSYROWID то папaшкин. И что тeперь искать всех детей лейтенанта Шмидта?
SY.
Таки да, сгенерировать по словарю запрос и искать.
Благо это не особо сложно в частном конкретном случае и не хлопотно по ресурсам при индексированных fk.
В общем случае - задача довольно сложная, не спорю.

Возможно не такая и сложная. Нужно просто в цикле по bulk exceptions выдать:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
drop table dropme_child purge;
drop table dropme_parent purge;
create table dropme_parent(id primary key) as select rownum from dual connect by level < 10;
create table dropme_child(ref_id) as select 2*(1+mod(rownum,3)) from dual connect by level < 10;
alter table dropme_child add constraint dropme_fk foreign key(ref_id) references dropme_parent(id);

set serveroutput on

declare type ltt is table of rowid index by binary_integer;
  lt ltt;
  dml_error exception;
  pragma exception_init(dml_error, -24381);
  l_err_cnt number;
begin
  select rowid bulk collect into lt
    from dropme_parent
   where id < 5;
  forall i in 1..lt.count save exceptions
    delete dropme_parent where rowid = lt(i);
exception
  when dml_error then
    l_err_cnt := sql%bulk_exceptions.count;
    for i in 1..l_err_cnt loop
      dbms_output.put_line('rowid="'|| lt(sql%bulk_exceptions(i).error_INDEX)||'", error= -'||sql%bulk_exceptions(i).error_code
      );
    begin
        execute immediate 'delete dropme_parent where rowid = :1'
          using lt(sql%bulk_exceptions(i).error_INDEX);
      exception
        when others
          then
            dbms_output.put_line(sqlerrm);
    end;
    end loop;
end;
/
rowid="AAANVBAAEAAAAMMAAB", error= -2292
ORA-02292: integrity constraint (SCOTT.DROPME_FK) violated - child record found
ORA-24381: error(s) in array DML
rowid="AAANVBAAEAAAAMMAAD", error= -2292
ORA-02292: integrity constraint (SCOTT.DROPME_FK) violated - child record found
ORA-24381: error(s) in array DML

PL/SQL procedure successfully completed.

SQL> 



SY.
...
Рейтинг: 0 / 0
исключения forall при каскадном удалении через констрейнты
    #39259692
dba123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
receiver,

Можно через log errors подсмотреть имя констрейнта
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
--drop table dropme_parent_errlog purge;
exec dbms_errlog.create_error_log('dropme_parent', 'dropme_parent_errlog');

declare 
  type ltt is table of rowid index by binary_integer;
  lt ltt;
  lc_unit constant varchar2(30) := 'my_unit';
  lc_dt   constant varchar2(20) := to_char(sysdate,'yyyymmdd hh24:mi:ss');
  dml_error exception;
  pragma exception_init(dml_error, -24381);
begin
  select rowid bulk collect into lt
    from dropme_parent
   where id < 5;
  forall i in 1..lt.count save exceptions
    delete  dropme_parent where rowid = lt(i) 
    log errors into dropme_parent_errlog (lc_dt||', '||lc_unit||'-'||$$plsql_line);

exception
  when dml_error then

    for v in ( select ora_err_tag$, ora_err_rowid$, ora_err_mesg$, id from dropme_parent_errlog where substr(ora_err_tag$,1,17) = lc_dt ) loop
     dbms_output.put_line(v.ora_err_tag$||', id="'||v.id||'", rowid="'||v.ora_err_rowid$||'", '||v.ora_err_mesg$);
    end loop;
    raise;

end;
/

--
20160621 14:42:02, my_unit-14, id="2", rowid="AAArE3AAGAADnxzAAB", ORA-02292: integrity constraint (SCOTT.DROPME_FK) violated - child record found
20160621 14:42:02, my_unit-14, id="4", rowid="AAArE3AAGAADnxzAAD", ORA-02292: integrity constraint (SCOTT.DROPME_FK) violated - child record found

ERROR:
ORA-24381: error(s) in array DML
ORA-06512: at line 22
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / исключения forall при каскадном удалении через констрейнты
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]