I was tasked to create triggers to insert into a log table when an order table was
- Inserted into
- updated
also insert/delete/update was to be disabled between 5pm friday and 9am monday. The solution that follows covers all this, however because it is a before trigger I have had to turn off integrity constraints (does this matter for a log table?)
Does anyone have any suggestions how I might be able to do this AND keep the integrity constraints (on the logono column)?
I was thinking about 11G compunt triggers but it was sugegsted in a previous answer that this would not be an appropriate use, plus the issue with backwards compatibility.
CREATE OR REPLACE TRIGGER log_order
BEFORE INSERT OR UPDATE OR DELETE ON orders
FOR EACH ROW
DECLARE out_of_hours EXCEPTION;
BEGIN
IF INSERTING THEN
IF
TO_NUMBER( TO_CHAR( SYSDATE, 'DHH24' ) ) BETWEEN 109 AND 517 THEN
insert into order_log values
(order_log_PK.nextval,
(select user from dual),
:NEW.ono,
(select SYSDATE from dual),
'Order Inserted' ) ;
ELSE
RAISE out_of_hours;
END IF;
END IF;
IF UPDATING THEN
IF
TO_NUMBER( TO_CHAR( SYSDATE, 'DHH24' ) ) BETWEEN 109 AND 517 THEN
insert into order_log values
(order_log_PK.nextval,
(select user from dual),
:NEW.ono,
(select SYSDATE from dual),
'order updated' ) ;
ELSE
RAISE out_of_hours;
END IF;
END IF;
IF DELETING THEN
IF
TO_NUMBER( TO_CHAR( SYSDATE, 'DHH24' ) ) BETWEEN 109 AND 517
THEN
RAISE out_of_hourS;
END IF;
END IF;
EXCEPTION
WHEN out_of_hours THEN
dbms_output.put_line('there is not privelages at this time');
RAISE_APPLICATION_ERROR(-20001, 'CANNOT UPDATE OUT OF HOURS');
END;
thanks
EDIT
The integrity issue came about becaue the :NEW.ono value going into the Log Table is not yet inserted into the order table due to this being a before trigger, therefore violating the logono Foreign Key.
You can simplify your trigger so that you only check the Monday 9am – Friday 5pm condition once, so that you only have one place where you insert into the log table, and to eliminate the need for an extra exception and an exception handler.
You can make the trigger an AFTER INSERT trigger so that the trigger executes after the data already exists in
ORDERSso that you could create a foreign key constraint inORDER_LOGthat references theONOkey inORDERS. However, it would seem very odd to want to create that sort of constraint. If you create your log table as a child of the base table, that would mean that you either would never be able to delete a row fromORDERS, since there would always be a child row, or that you would need to delete all the rows fromORDER_LOGfor thatONObefore doing the delete. Neither of those is generally particularly desirable– in general, the point of having a log table is that it will log all the operations, not just the operations on rows in the base table that are still present.While it may be syntactically valid to do an
INSERTinto a table without listing the columns you are inserting into, doing so is dangerous. If you add another column in the future, even if it is not required, yourINSERTwill start failing. If you list the columns explicitly, the trigger will continue to work. It is also relatively hard to spot bugs where data is being inserted into the wrong column if you don’t list the columns explicitly. I guessed at what the columns were– you’ll have to substitute the proper column names.