Answer the question
In order to leave comments, you need to log in
Why does an error occur in sql trigger (Oracle DB)?
I work with Oracle Web Center Content.
We set the task of making a mechanism for automatically assigning a registration number to a document. I decided to create a trigger in the database that works when a new document record is created.
Before me were 2 tasks: the usual registration of the document, the registration of the past number. There are no problems with the usual registration, but with the registration of the past date, there were difficulties.
In fact, if a document is registered with a past date, then you need to find the last document on this date with the desired protection group and add a letter after the serial number of the document to the registration number. It seems that I found where the error occurs (when I get the registration number of the required document), but I don’t know how to fix it.
Here is the code with comments:
create or replace
TRIGGER ZID_DOCMETA_TRG
BEFORE INSERT ON DOCMETA
FOR EACH ROW
DECLARE CNT NUMBER := 0; -- порядковый номер регистрируемого документа
doctype DOCTYPES.DDESCRIPTION%type;-- тип документа
SEQURITYGROUP revisions.dsecuritygroup%TYPE; --группа защиты
SIMV VARCHAR(10); -- нужно для получения первых 2 символов типа документа
data_reg_c date;
--data_reg varchar(20); --дата регистрации документа, для регистрации задним числом
data_reg varchar(10);
last_id REVISIONS.DID%type; --последний документ зарегистрированный за день
last_reg_nomer varchar2(30); --регистрационный номер последнего документа за день
simvol varchar(10); --место, куда вставить символ при регистрации прошедшим числом числом
BEGIN
SELECT R.dsecuritygroup, r.dindate, d.ddescription INTO SEQURITYGROUP, data_reg_c, doctype FROM REVISIONS R, doctypes d
WHERE R.DID = :NEW.DID and d.ddoctype = r.ddoctype; --получаем значения полей
SELECT to_char(data_reg_c,'dd.mm.yy') into data_reg from dual;
if (data_reg = to_char(sysdate,'dd.mm.yy')) then -- регистрация документа сегодняшним числом
begin
CNT := REG_NAMBER_SEQ.NEXTVAL;-- следующий порядковый номер из счетчика
SELECT SUBSTR(doctype,1,2) INTO SIMV FROM DUAL; -- 2 символа типа документа
IF ((SEQURITYGROUP = 'Общие') or (SEQURITYGROUP = 'Public')) THEN -- если общий документ
SELECT SIMV || '-' || '/' || CNT || '-' || TO_CHAR(SYSDATE,'YYYY') INTO :NEW.XZID_VKH_NOMER FROM DUAL;
end if;
IF ((SEQURITYGROUP != 'Общие') and (SEQURITYGROUP != 'Public')) THEN -- если есть группа защиты
SELECT SIMV || '-' || '/' || CNT || '-' || TO_CHAR(SYSDATE,'YYYY') || SEQURITYGROUP INTO :NEW.XZID_VKH_NOMER FROM DUAL;
END IF;
end;
end if;
if (data_reg < to_char(sysdate,'dd.mm.yy')) then - регистрация документа прошедшей датой
begin
SELECT MAX(did) into last_id from DEV_OCS.Revisions
where ((to_char(DINDATE,'dd.mm.yy') < data_reg) or (to_char(DINDATE,'dd.mm.yy') = data_reg)) and (dsecuritygroup = SEQURITYGROUP); -- здесь получаем последний id на который был зарегистрирован документ за введенное число или раньше с нужной группой защиты
SELECT XZID_VKH_NOMER into last_reg_nomer from dev_ocs.docmeta
where docmeta.did = last_id; --получаем регистрационный номер нужного документа. Вот в этом месте вылетает с ошибкой.
SELECT substr(last_reg_nomer,instr(last_reg_nomer,'-'||to_CHAR(data_reg_c,'YYYY'))-1,1) into simvol from dual;
IF ((SEQURITYGROUP = 'Общие') or (SEQURITYGROUP = 'Public')) THEN
begin
SELECT replace(last_reg_nomer,'-'||to_char(data_reg_c,'YYYY')) into last_reg_nomer from dual;
if ((ascii(simvol)<97) or ascii(simvol)>122) then
SELECT last_reg_nomer||chr(97)|| '-' || TO_CHAR(SYSDATE,'YYYY') INTO :NEW.XZID_VKH_NOMER FROM DUAL;
end if;
if ((ascii(simvol)>96) and ascii(simvol)<122) then
SELECT last_reg_nomer||chr(ascii(simvol)+1)|| '-' || TO_CHAR(SYSDATE,'YYYY') INTO :NEW.XZID_VKH_NOMER FROM DUAL;
end if;
if (ascii(simvol)=122) then
begin
select replace(last_reg_nomer,'z','a') into last_reg_nomer from dual;
SELECT last_reg_nomer||chr(97)|| '-' || TO_CHAR(SYSDATE,'YYYY') INTO :NEW.XZID_VKH_NOMER FROM DUAL;
end;
end if;
end;
end if;
IF ((SEQURITYGROUP != 'Общие') and (SEQURITYGROUP != 'Public')) then
begin
select replace(last_reg_nomer,'-'||to_char(data_reg_c,'YYYY')||SEQURITYGROUP) into last_reg_nomer from dual;
if ((ascii(simvol)<97) or ascii(simvol)>122) then
SELECT last_reg_nomer||chr(97)|| '-' || TO_CHAR(SYSDATE,'YYYY')||SEQURITYGROUP INTO :NEW.XZID_VKH_NOMER FROM DUAL;
end if;
if ((ascii(simvol)>96) and ascii(simvol)<122) then
SELECT last_reg_nomer||chr(ascii(simvol)+1)|| '-' || TO_CHAR(SYSDATE,'YYYY')||SEQURITYGROUP INTO :NEW.XZID_VKH_NOMER FROM DUAL;
end if;
if (ascii(simvol)=122) then
begin
select replace(last_reg_nomer,'z','a') into last_reg_nomer from dual;
SELECT last_reg_nomer||chr(97)|| '-' || TO_CHAR(SYSDATE,'YYYY')||SEQURITYGROUP INTO :NEW.XZID_VKH_NOMER FROM DUAL;
end;
end if;
end;
end if;
end;
end if;
END;
Answer the question
In order to leave comments, you need to log in
How could I fix the error occurs in these requests:
SELECT MAX(did) into last_id from DEV_OCS.Revisions
where ((to_char(DINDATE,'dd.mm.yy') < data_reg) or (to_char(DINDATE,'dd.mm.yy') = data_reg)) and (dsecuritygroup = SEQURITYGROUP);
-- здесь получаем последний id на который был зарегистрирован документ за введенное число или раньше с нужной группой защиты
SELECT XZID_VKH_NOMER into last_reg_nomer from dev_ocs.docmeta
where docmeta.did = last_id; --получаем регистрационный номер нужного документа. Вот в этом месте вылетает с ошибкой.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question