Oracle SQL checking for overlapped dates using a trigger

风格不统一 提交于 2021-01-01 00:50:58

问题


I have the table named EPOCA with this schema:

CREATE TABLE EPOCA
(
    ID       INT
        CONSTRAINT PK_EPOCA PRIMARY KEY,
    NOME     VARCHAR(250),
    DATE_INITIAL DATE
        CONSTRAINT NN_EPOCA_DATA_INI NOT NULL,
    DATE_END DATE,
    CONSTRAINT CK_EPOCA_DATAS CHECK (DATE_INITIAL < DATE_END)
);

And even though I already check if the initial date is smaller then the end date, I need to check that when I insert a new EPOCA the dates I insert will not overlap with any of the present dates.

I developed this trigger:

CREATE OR REPLACE TRIGGER TRGEPOCASNAOSOBREPOSTAS
BEFORE INSERT OR UPDATE
ON EPOCA
FOR EACH ROW

DECLARE
    FLAG_DATE NUMBER;
BEGIN
    FLAG_DATE := 0;

    IF INSERTING THEN
        SELECT E.ID INTO FLAG_DATE FROM EPOCA E WHERE E.DATE_INITIAL < :NEW.DATE_INITIAL AND E.DATE_END > :NEW.DATE_END;
        IF FLAG_DATE <> 0 THEN
            RAISE_APPLICATION_ERROR(-2098, 'INSERT FAILED BECAUSE SELECTED DATES OVERLAP EXISTENT ONES');
        END IF;
    ELSIF UPDATING THEN
        SELECT E.ID INTO FLAG_DATE FROM EPOCA E WHERE E.DATE_INITIAL < :NEW.DATE_INITIAL AND E.DATA_END > :NEW.DATA_END;
        IF FLAG_DATE <> 0 THEN
            RAISE_APPLICATION_ERROR(-2099, 'UPDATE FAILED BECAUSE SELECTED DATES OVERLAP EXISTENT ONES');
        END IF;
    END IF;
END;

The error I am getting when inserting is because no data was found on line 7 of the trigger and when I am updating the table the error is because the table is in mutation and the trigger cannot read the table, which makes sense but I don't know how to solve it.

Any suggestions on how to solve this problem?


回答1:


You should use the count aggregate function in your select query at both places as it always returns tge count evenif it is zero as follows:

...
...
SELECT count(*) INTO FLAG_DATE FROM EPOCA E WHERE E.DATA_INI < :NEW.DATA_INI AND E.DATA_FIM > :NEW.DATA_FIM;
IF FLAG_DATE <> 0 THEN
...
...



回答2:


You don't need a SELECT statement, but convert your code to the one such as below

CREATE OR REPLACE TRIGGER TRGEPOCASNAOSOBREPOSTAS
BEFORE UPDATE
ON EPOCA
FOR EACH ROW
DECLARE
    FLAG_DATE NUMBER;
BEGIN
    FLAG_DATE := 0;

    IF UPDATING THEN
        IF :OLD.DATE_INITIAL < :NEW.DATE_INITIAL AND :OLD.DATE_END > :NEW.DATE_END THEN
           FLAG_DATE := :OLD.ID;
        END IF;
        IF FLAG_DATE <> 0 THEN
            RAISE_APPLICATION_ERROR(-2099, 'UPDATE FAILED BECAUSE SELECTED DATES OVERLAP EXISTENT ONES');
        END IF;
    END IF;
END;
/

where no need to use INSERTING case( the trigger should be BEFORE UPDATE only ). Since the desired condition is already provided as the check constraint within the table's definition.



来源:https://stackoverflow.com/questions/65277494/oracle-sql-checking-for-overlapped-dates-using-a-trigger

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!