Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / исключения forall при каскадном удалении через констрейнты / 14 сообщений из 14, страница 1 из 1
20.06.2016, 13:18:05
    #39258827
receiver
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
исключения forall при каскадном удалении через констрейнты
Вижу в чужой системе "заглавную" таблицу и иерархию подчиненных таблиц. До пятого уровня включительно.
Для удаления старых записей, разработчик понавтыкал во все таблицы всех уровней 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
20.06.2016, 13:25:11
    #39258832
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
исключения forall при каскадном удалении через констрейнты
receiverМогу ли я понять, какая запись и в какой таблице, при этом каскадном удалении была причиной ошибки?Нет. При SAVE EXCEPTIONS есть только код ошибки. Вывод - отказаться от притянутого за уши FORALL.
...
Рейтинг: 0 / 0
20.06.2016, 13:31:51
    #39258836
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
исключения forall при каскадном удалении через констрейнты
ElicreceiverМогу ли я понять, какая запись и в какой таблице, при этом каскадном удалении была причиной ошибки?Нет. При SAVE EXCEPTIONS есть только код ошибки. Вывод - отказаться от притянутого за уши FORALL.
%BULK_EXCEPTIONS(i).ERROR_INDEX - не?
...
Рейтинг: 0 / 0
20.06.2016, 13:47:55
    #39258853
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
исключения forall при каскадном удалении через констрейнты
andrey_anonymousElicreceiverМогу ли я понять, какая запись и в какой таблице, при этом каскадном удалении была причиной ошибки?Нет. При SAVE EXCEPTIONS есть только код ошибки. Вывод - отказаться от притянутого за уши FORALL.%BULK_EXCEPTIONS(i).ERROR_INDEX - не?Подумай сам.
...
Рейтинг: 0 / 0
20.06.2016, 14:26:51
    #39258886
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
исключения forall при каскадном удалении через констрейнты
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
20.06.2016, 15:07:56
    #39258910
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
исключения forall при каскадном удалении через констрейнты
andrey_anonymousПодумал.Недостаточно. Вопрос был не в том, какой папа не удалился, а в том, какой из многочисленных детей этому помешал.
...
Рейтинг: 0 / 0
20.06.2016, 15:13:27
    #39258915
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
исключения forall при каскадном удалении через констрейнты
Elicandrey_anonymousПодумал.Недостаточно. Вопрос был не в том, какой папа не удалился, а в том, какой из многочисленных детей этому помешал.
Ну от кого-кого, а от тебя не ожидал - словарем и dbms_% пользоваться ты точно умеешь :)
В конкретном сценарии ТС задача решается, причем даже не очень сложно.
В более общем случае - сложнее, да.
...
Рейтинг: 0 / 0
20.06.2016, 15:16:15
    #39258923
ora601
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
исключения forall при каскадном удалении через констрейнты
receiverМогу ли я понять, какая запись и в какой таблице, при этом каскадном удалении была причиной ошибки?

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


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

SY.
...
Рейтинг: 0 / 0
20.06.2016, 15:54:26
    #39258967
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
исключения forall при каскадном удалении через констрейнты
andrey_anonymousНу от кого-кого, а от тебя не ожидал - словарем и dbms_% пользоваться ты точно умеешь :)Аналогично. Неприятно удивлён. Спишу на отсутствие практического опыта. Ещё раз
ElicПри SAVE EXCEPTIONS есть только код ошибки.Как следствие - нет параметров текста ошибки.
...
Рейтинг: 0 / 0
20.06.2016, 16:12:17
    #39258986
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
исключения forall при каскадном удалении через констрейнты
SYROWID то папaшкин. И что тeперь искать всех детей лейтенанта Шмидта?
SY.
Таки да, сгенерировать по словарю запрос и искать.
Благо это не особо сложно в частном конкретном случае и не хлопотно по ресурсам при индексированных fk.
В общем случае - задача довольно сложная, не спорю.
...
Рейтинг: 0 / 0
20.06.2016, 16:47:01
    #39259028
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
исключения forall при каскадном удалении через констрейнты
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
21.06.2016, 14:57:54
    #39259692
dba123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
исключения forall при каскадном удалении через констрейнты
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
Форумы / Oracle [игнор отключен] [закрыт для гостей] / исключения forall при каскадном удалении через констрейнты / 14 сообщений из 14, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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