У меня есть некоторая процедура, которые выполняют оператор 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;
Некоторые триггеры и ограничения применяются к таблице, они могут повредиться, ВСТАВЛЯЮТ. Как я могу зарегистрироваться в теле процедуры - если ВСТАВКА была успешна или нет?
Конечно, я могу назвать количество () в голове и в конце процедуры, но это будет не так корректное решение.
Вы можете использовать пункт 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;
Взято по этой ссылке:
Вы можете проверить значение SQL%ROWCOUNT, чтобы узнать, действительно ли строка была вставлена. Я думаю, что было бы очень плохой практикой иметь триггер, который не смог (или решил не делать) вставить запись без поднятия исключения, но это может произойти.
Также, ваше утверждение "откат;" является избыточным, и должно быть изменено на нечто подобное:
EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('SQLCODE=' || SQLCODE || ' SQLERRM=''' || SQLERRM || ''''); RAISE; END;
Команда RAISE поднимет то же самое исключение, которое было поймано триггером, так что ваша вызывающая программа будет знать, почему она не смогла (в дополнение к отладке dbms_output).
.В блоке исключений необходимо дать дамп содержимого SQLCODE и SQLERRM, чтобы было видно, какие ошибки вы получаете. Возможно, вам поможет следующее добавление в обработчик КОГДА ДРУГИЕ:
DBMS_OUTPUT.PUT_LINE('SQLCODE=' || SQLCODE ||
' SQLERRM=''' || SQLERRM || '''');
Share and enjoy.
ИСКЛЮЧИТЬ ВЫСТАВКУ... КОГДА ДРУГИЕ
Действительно, вопрос должен заключаться не в том, как проверить, удастся ли это сделать, а в том, что делать, если это не удастся.
.При нарушении ограничений будет брошено исключение, и вы окажетесь в своем блоке обработки исключений.
Какие триггеры мешают вам вставить? Можете ли вы тоже бросить туда исключение?