#oracle #plsql
#Oracle #plsql
Вопрос:
Мне нужна помощь в следующем:
У меня есть следующая таблица:
CREATE TABLE LOG_PUSH_READOUTS_HEADERS
(
ID NUMBER NOT NULL,
PUSH_DATE DATE NOT NULL,
SOURCE_SERIAL VARCHAR2(100) NOT NULL,
SOURCE_START_DATE DATE NOT NULL,
SOURCE_END_DATE DATE NOT NULL,
SOURCE_RUS_TYPE_ID NUMBER,
OUTPUT_SERIAL VARCHAR2(100) NOT NULL,
FILTERS_RUS VARCHAR2(100),
FILTERS_INDICATORS VARCHAR2(100),
CONSTRAINT id_pk PRIMARY KEY (ID)
);
Мне нужно реализовать следующую процедуру:
Входными параметрами для вставки в таблицу являются все столбцы, кроме ID, для которых нам нужно создать секвенсор. Выходными параметрами являются ID и RESULT_CODE. ID — это вставляемое значение первичного ключа. RESULT_CODE равен нулю, если процедура прошла успешно, или некоторому значению в интервале 9000-9999. Используйте RESULT_CODE для ошибок, например, RESULT_CODE 9123 — «FILTER_RUS не может быть нулевым».
Вот моя попытка:
CREATE OR REPLACE PROCEDURE INSERT_HEADER
(PUSH_DATE IN DATE, SOURCE_SERIAL IN VARCHAR2, SOURCE_START_DATE IN DATE, SOURCE_END_DATE IN DATE, SOURCE_RUS_TYPE_ID IN NUMBER,
OUTPUT_SERIAL IN VARCHAR2, FILTERS_RUS IN VARCHAR2, FILTERS_INDICATORS IN VARCHAR2, ID OUT NUMBER, RESULT_CODE OUT NUMBER)
IS
hd_seq NUMBER;
BEGIN
SELECT AMM_MDM.Header_Seq.NEXTVAL INTO hd_seq FROM DUAL;
ID:=hd_seq;
INSERT INTO AMM_MDM.LOG_PUSH_READOUTS_HEADERS (PUSH_DATE IN DATE, SOURCE_SERIAL IN VARCHAR2, SOURCE_START_DATE IN DATE,
SOURCE_END_DATE IN DATE, SOURCE_RUS_TYPE_ID IN NUMBER,
OUTPUT_SERIAL IN VARCHAR2, FILTERS_RUS IN VARCHAR2, FILTERS_INDICATORS IN VARCHAR2)
VALUES (PUSH_DATE, SOURCE_SERIAL, SOURCE_START_DATE,
SOURCE_END_DATE, SOURCE_RUS_TYPE_ID,
OUTPUT_SERIAL, FILTERS_RUS, FILTERS_INDICATORS)
END;
Как установить RESULT_CODE в интервале 9000-9999? Как управлять ошибками?
Ответ №1:
Насколько я понял вопрос, это будет похоже на следующий пример. Я сократил список столбцов (не хотелось так сильно привязываться), но вы должны быть в состоянии получить общую идею.
create or replace procedure p_insert_header
(p_push_date in date,
p_source_serial in varchar2,
p_filter_rus in varchar2,
--
p_id out number,
p_result_code out number
)
is
l_id number;
begin
-- check for errors
if p_push_date is null then
p_result_code := 1234;
elsif p_source_serial not in ('A', 'B', 'C') then
p_result_code := 5532;
elsif p_filter_rus is null then
p_result_code := 9123;
end if;
-- if there are no errors, do insert
if p_result_code is null then
-- fetch sequence number
p_id := header_seq.nextval;
insert into log_push_readouts_headers
(id, push_date, source_serial, filter_rus)
values
(p_id, p_push_date, p_source_serial, p_filter_rus);
end if;
end;
В конце, как только процедура завершится, она вернет исходящие параметры:
- ID:
- некоторый порядковый номер, если все было в порядке
- NULL, если оно не было
- РЕЗУЛЬТИРУЮЩИЙ КОД:
- NULL, если все было в порядке
- номер ошибки, если она не была
Ответ №2:
Для пользовательских ошибок Oracle допускает отрицательные целые числа в диапазоне -20000 .. -20999
. Вам необходимо удалить объявления типов данных для списка столбцов инструкции insert
CREATE OR REPLACE PROCEDURE INSERT_HEADER(PUSH_DATE IN DATE,
SOURCE_SERIAL IN VARCHAR2,
SOURCE_START_DATE IN DATE,
SOURCE_END_DATE IN DATE,
SOURCE_RUS_TYPE_ID IN NUMBER,
OUTPUT_SERIAL IN VARCHAR2,
FILTERS_RUS IN VARCHAR2,
FILTERS_INDICATORS IN VARCHAR2,
ID OUT NUMBER,
RESULT_CODE OUT NUMBER)
IS
BEGIN
INSERT INTO LOG_PUSH_READOUTS_HEADERS
(ID,
PUSH_DATE,
SOURCE_SERIAL,
SOURCE_START_DATE,
SOURCE_END_DATE,
SOURCE_RUS_TYPE_ID,
OUTPUT_SERIAL,
FILTERS_RUS,
FILTERS_INDICATORS)
VALUES
(Header_Seq.NEXTVAL,
PUSH_DATE,
SOURCE_SERIAL,
SOURCE_START_DATE,
SOURCE_END_DATE,
SOURCE_RUS_TYPE_ID,
OUTPUT_SERIAL,
FILTERS_RUS,
FILTERS_INDICATORS);
--Suppose some opertions performed and gave the RESULT_CODE value below
RESULT_CODE := 20123;
IF RESULT_CODE = 20123 THEN raise_application_error(-RESULT_CODE, 'FILTER_RUS cannot be null');
--ELSIF RESULT_CODE = 20124 THEN raise_application_error(-RESULT_CODE, 'Some other message 1');
--ELSIF RESULT_CODE = 20125 THEN raise_application_error(-RESULT_CODE, 'Some other message 2');
END IF;
END;
В этом случае он выбрасывает сообщение : FILTER_RUS cannot be null