V
V
Vergileey2014-05-12 13:27:22
Oracle
Vergileey, 2014-05-12 13:27:22

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;

I'm not very good at SQL. Explain what I'm doing wrong.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexey Skahin, 2014-05-12
@pihel

Where is the error, what does it look like?

V
Vergileey, 2014-05-12
@Vergileeey

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; --получаем регистрационный номер нужного документа. Вот в этом месте вылетает с ошибкой.

If in the second request to substitute value of an index of the document instead of last_id fulfills normally. If processed not in a trigger, but simply in a sql editor, then it also works. But I can't figure out why it doesn't work the way it is.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question