Проверьте, была ли ВСТАВКА успешна

У меня есть некоторая процедура, которые выполняют оператор INSERT:

CREATE OR REPLACE PROCEDURE potok_insert(
  p_jfplate IN potok.jfplate%TYPE,
  p_post IN potok.post%TYPE,
  p_jfchan IN potok.jfchan%TYPE,
  p_jfdatetime IN VARCHAR2 
  ) 
AS 
  t_jfdatetime TIMESTAMP:=TO_TIMESTAMP(p_jfdatetime,'DD.MM.YYYY HH24:MI:SS');
BEGIN
  INSERT INTO potok (jfplate, post, jfchan, jfdate_y, jfdate_m, jfdate_d, jftime, jfdatetime, 
    dt_reg, ibd_arx)
      VALUES (RTRIM(p_jfplate),
        p_post, 
        RTRIM(p_jfchan), 
        EXTRACT(YEAR FROM t_jfdatetime), 
        EXTRACT(MONTH FROM t_jfdatetime), 
        EXTRACT(DAY FROM t_jfdatetime), 
        LPAD(EXTRACT(HOUR FROM t_jfdatetime),2,'0')||':'||
        LPAD(EXTRACT(MINUTE FROM t_jfdatetime),2,'0')||':'||
        LPAD(EXTRACT(SECOND FROM t_jfdatetime),2,'0'), 
        CAST(t_jfdatetime AS DATE),
        SYSDATE,
        1);  
EXCEPTION
  WHEN OTHERS THEN
    ROLLBACK;
END potok_insert;

Некоторые триггеры и ограничения применяются к таблице, они могут повредиться, ВСТАВЛЯЮТ. Как я могу зарегистрироваться в теле процедуры - если ВСТАВКА была успешна или нет?

Конечно, я могу назвать количество () в голове и в конце процедуры, но это будет не так корректное решение.

5
задан Cœur 9 April 2017 в 09:10
поделиться

5 ответов

Вы можете использовать пункт RETURNING, чтобы вернуть rowid только что созданной вами строки, например:

CREATE SEQUENCE seq_emp;

set serveroutput on

DECLARE
 x emp.empno%TYPE;
BEGIN
  INSERT INTO emp
  (empno, ename)
  VALUES
  (seq_emp.NEXTVAL, 'Morgan')
  RETURNING empno
  INTO x;

  dbms_output.put_line(x);
END;
/

DECLARE
 r rowid;
BEGIN
  INSERT INTO emp
  (empno, ename)
  VALUES
  (seq_emp.NEXTVAL, 'Morgan')
  RETURNING rowid
  INTO r;

  dbms_output.put_line(r);
END;
/

DECLARE
 x emp.empno%TYPE;
 r rowid;
BEGIN
  INSERT INTO emp
  (empno, ename)
  VALUES
  (seq_emp.NEXTVAL, 'Morgan')
  RETURNING rowid, empno
  INTO r, x;

  dbms_output.put_line(r); 
  dbms_output.put_line(x);
END;

Взято по этой ссылке:

http://www.psoug.org/reference/insert.html

7
ответ дан 18 December 2019 в 09:50
поделиться

Вы можете проверить значение SQL%ROWCOUNT, чтобы узнать, действительно ли строка была вставлена. Я думаю, что было бы очень плохой практикой иметь триггер, который не смог (или решил не делать) вставить запись без поднятия исключения, но это может произойти.

Также, ваше утверждение "откат;" является избыточным, и должно быть изменено на нечто подобное:

EXCEPTION WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('SQLCODE=' || SQLCODE ||
                     '  SQLERRM=''' || SQLERRM || '''');
RAISE;
END;

Команда RAISE поднимет то же самое исключение, которое было поймано триггером, так что ваша вызывающая программа будет знать, почему она не смогла (в дополнение к отладке dbms_output).

.
1
ответ дан 18 December 2019 в 09:50
поделиться

В блоке исключений необходимо дать дамп содержимого SQLCODE и SQLERRM, чтобы было видно, какие ошибки вы получаете. Возможно, вам поможет следующее добавление в обработчик КОГДА ДРУГИЕ:

DBMS_OUTPUT.PUT_LINE('SQLCODE=' || SQLCODE ||
                     '  SQLERRM=''' || SQLERRM || '''');

Share and enjoy.

1
ответ дан 18 December 2019 в 09:50
поделиться

ИСКЛЮЧИТЬ ВЫСТАВКУ... КОГДА ДРУГИЕ

Действительно, вопрос должен заключаться не в том, как проверить, удастся ли это сделать, а в том, что делать, если это не удастся.

.
6
ответ дан 18 December 2019 в 09:50
поделиться

При нарушении ограничений будет брошено исключение, и вы окажетесь в своем блоке обработки исключений.

Какие триггеры мешают вам вставить? Можете ли вы тоже бросить туда исключение?

2
ответ дан 18 December 2019 в 09:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: