Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 как выявить значение при котором произошел exception?  [new]
нонейм
Guest
Можно ли выявить значение или столбец при котором произошло исключение?

CREATE OR REPLACE TRIGGER tbn_t
  BEFORE insert OR UPDATE on tbn
  for each ROW
DECLARE
  lv_sqlerrm VARCHAR2(240);     -- Место для хранения SQLERRM
BEGIN
   INSERT INTO tbn(tbn_id, d_number, d_date, d_type, f_id)
        VALUES (:NEW.tbn_id, :NEW.d_number,:NEW.d_date,:NEW.d_type,:NEW.f_id);
EXCEPTION
  WHEN OTHERS THEN
    lv_sqlerrm := SQLERRM;
    IF ( lv_sqlcode = -01722 ) THEN
      INSERT INTO logs(TB_NAME_ID, F_ERROR, ERR_MESG)
             VALUES ('tbn','1',lv_sqlerrm);  --< здесь хотелось бы записать ('tbn','1','"d_number" не может быть "№15/68887"')
    END IF;
end tbn_t;
20 дек 11, 15:00    [11797016]     Ответить | Цитировать Сообщить модератору
 Re: как выявить значение при котором произошел exception?  [new]
metrAniksaraT
Member

Откуда: Kiev
Сообщений: 135
нонейм,
1) Указывай в логе все значения строки, где произошла ошибка. Вместе с текстом сообщения об ошибке.
2) Или обрабатывай предварительно каждое значение по отдельности, например:
begin
  v_n := TO_NUMBER(d_number);
exception
  ...
end;
20 дек 11, 15:13    [11797143]     Ответить | Цитировать Сообщить модератору
 Re: как выявить значение при котором произошел exception?  [new]
mcureenab
Member

Откуда: Murmansk
Сообщений: 5928
нонейм,

используй промежуточную переменную для проверок:

rec tbn%rowtype;

по мере инициализации:

rec.tbn_id := :NEW.tbn_id;

...

В какой строке рванёт, то поле и invalid.
20 дек 11, 15:17    [11797191]     Ответить | Цитировать Сообщить модератору
 Re: как выявить значение при котором произошел exception?  [new]
Сергей Арсеньев
Member

Откуда:
Сообщений: 4118
нонейм
Можно ли выявить значение или столбец при котором произошло исключение?
CREATE OR REPLACE TRIGGER tbn_t
  BEFORE insert OR UPDATE on tbn
  for each ROW
DECLARE
  lv_sqlerrm VARCHAR2(240);     -- Место для хранения SQLERRM
BEGIN
   INSERT INTO tbn(tbn_id, d_number, d_date, d_type, f_id)
        VALUES (:NEW.tbn_id, :NEW.d_number,:NEW.d_date,:NEW.d_type,:NEW.f_id);

IMHO первое попавшееся. :)

P.S. Я наверное туплю, но Вы хотите перед вставкой строки в таблицу вставить еще одну такую же строку в нее?
20 дек 11, 15:24    [11797283]     Ответить | Цитировать Сообщить модератору
 Re: как выявить значение при котором произошел exception?  [new]
нонейм
Guest
mcureenab
нонейм,

используй промежуточную переменную для проверок:

rec tbn%rowtype;

по мере инициализации:

rec.tbn_id := :NEW.tbn_id;

...

В какой строке рванёт, то поле и invalid.


прошу прощенья я не правильно пример написал. При внесении данных в одну таблицу должны обновляться некоторые поля другой таблицы, и поля не всегда совпадают:

CREATE OR REPLACE TRIGGER tbn2_t
  BEFORE insert OR UPDATE on tbn2
  for each ROW
DECLARE
  lv_sqlerrm VARCHAR2(240);     -- Место для хранения SQLERRM
BEGIN
   INSERT INTO tbn(tbn_id, d_number, d_date, d_type, f_id)
        VALUES (:NEW.tbn2_id, :NEW.d_number,:NEW.d_date,:NEW.d_type,:NEW.f2_id);
EXCEPTION
  WHEN OTHERS THEN
    lv_sqlerrm := SQLERRM;
    IF ( lv_sqlcode = -01722 ) THEN
      INSERT INTO logs(TB_NAME_ID, F_ERROR, ERR_MESG)
             VALUES ('tbn','1',lv_sqlerrm);  --< здесь хотелось бы записать ('tbn','1','"d_number" не может быть "№15/68887"')
    END IF;
end tbn2_t;
20 дек 11, 15:24    [11797288]     Ответить | Цитировать Сообщить модератору
 Re: как выявить значение при котором произошел exception?  [new]
mcureenab
Member

Откуда: Murmansk
Сообщений: 5928
нонейм,

"некоторые поля другой таблицы"?? insert заполняет все поля записи - явными значениями из values, из default или null.
20 дек 11, 15:47    [11797554]     Ответить | Цитировать Сообщить модератору
 Re: как выявить значение при котором произошел exception?  [new]
нонейм
Guest
mcureenab
нонейм,

"некоторые поля другой таблицы"?? insert заполняет все поля записи - явными значениями из values, из default или null.


ну да, некоторые поля другой таблицы заполняются явными значениями, все остальное NULL'ами
20 дек 11, 15:52    [11797612]     Ответить | Цитировать Сообщить модератору
 Re: как выявить значение при котором произошел exception?  [new]
mcureenab
Member

Откуда: Murmansk
Сообщений: 5928
нонейм,

делай

rec.tbn_id := :NEW.tbn_id;

только для тех полей, которые перечислены в insert values .

Потом rec можно не использовать ни для чего, а можно

insert into tbn values rec;
20 дек 11, 16:10    [11797865]     Ответить | Цитировать Сообщить модератору
 Re: как выявить значение при котором произошел exception?  [new]
нонейм
Guest
mcureenab,

спасибо) Сейчас попробую.
20 дек 11, 16:20    [11797997]     Ответить | Цитировать Сообщить модератору
 Re: как выявить значение при котором произошел exception?  [new]
нонейм
Guest
mcureenab,

А как потом при записи ошибки выявить какой столбец и значение ошибочное?
Получилось так, но кажется это не айс. И тут только значение можно получить.
temp := :NEW.tbn2_ID;  rec.tbn_ID   := :NEW.tbn2_ID;
temp := :NEW.D_NUMBER; rec.D_NUMBER := :NEW.D_NUMBER;
temp := :NEW.D_DATE;   rec.D_DATE   := :NEW.D_DATE;
temp := :NEW.D_TYPE;   rec.D_TYPE   := :NEW.D_TYPE;
temp := :NEW.F_ID;     rec.F_ID     := :NEW.F_ID;
21 дек 11, 08:14    [11800516]     Ответить | Цитировать Сообщить модератору
 Re: как выявить значение при котором произошел exception?  [new]
mcureenab
Member

Откуда: Murmansk
Сообщений: 5928
Чего то тут не хватает...

нонейм
mcureenab,

А как потом при записи ошибки выявить какой столбец и значение ошибочное?
Получилось так, но кажется это не айс. И тут только значение можно получить.
temp varchar2(35);

temp := ':NEW.tbn2_ID';  rec.tbn_ID   := :NEW.tbn2_ID;
temp := ':NEW.D_NUMBER'; rec.D_NUMBER := :NEW.D_NUMBER;
temp := ':NEW.D_DATE';   rec.D_DATE   := :NEW.D_DATE;
temp := ':NEW.D_TYPE';   rec.D_TYPE   := :NEW.D_TYPE;
temp := ':NEW.F_ID';     rec.F_ID     := :NEW.F_ID;
temp := '';

exception
when ... then
    '... column:'||temp;
21 дек 11, 09:13    [11800660]     Ответить | Цитировать Сообщить модератору
 Re: как выявить значение при котором произошел exception?  [new]
нонейм
Guest
mcureenab,

это понятно) Так и есть, просто чтобы получить еще и столбец, тогда код должен быть такой:

...
temp := :NEW.tbn2_ID;   temp2 := 'tbn2_ID';  rec.tbn_ID   := :NEW.tbn2_ID;
temp := :NEW.D_NUMBER;  temp2 := 'D_NUMBER'; rec.D_NUMBER := :NEW.D_NUMBER;
temp := :NEW.D_DATE;    temp2 := 'D_DATE';   rec.D_DATE   := :NEW.D_DATE;
temp := :NEW.D_TYPE;    temp2 := 'D_TYPE';   rec.D_TYPE   := :NEW.D_TYPE;
temp := :NEW.F_ID;      temp2 := 'F_ID';     rec.F_ID     := :NEW.F_ID;
...
EXCEPTION
  WHEN OTHERS THEN
  temp2||' не может быть '||temp;


мне кажется можно сделать динамичнее. Только я не знаю как...
21 дек 11, 10:09    [11800963]     Ответить | Цитировать Сообщить модератору
 Re: как выявить значение при котором произошел exception?  [new]
mcureenab
Member

Откуда: Murmansk
Сообщений: 5928
нонейм,

Узнать, на каком поле рвануло, можно анализируя стек, но в стеке ты увидишь только строку и её всё равно придётся перекодировать в термины колонок и значений. Т.е. небольшой код в штатном потоке управления превратиться в монстра в обработчике исключений.

В динамический SQL я думаю не стоит влезать, поскольку задача решается на этапе разработки.
21 дек 11, 11:29    [11801424]     Ответить | Цитировать Сообщить модератору
 Re: как выявить значение при котором произошел exception?  [new]
Нонейм
Guest
mcureenab,

Спасибо, за хороший ответ! Премного благодарен)
21 дек 11, 18:27    [11805393]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить