I\'ve read the Oracle docs on creating triggers and am doing things exactly how it shows, however this just isn\'t working. My goal is to update the TPM_PROJECT table with the
A few issues in no particular order.
First, in the body of a row-level trigger, you need to use :new
and :old
to reference the new and old records. The leading colon is necessary. So your WHERE
clause would need to be
WHERE PROJECTID = :new.PROJECTID
Second, if you are running your CREATE TRIGGER
in SQL*Plus, you can get a list of the errors and warnings using the SHOW ERRORS
command, i.e.
SQL> show errors
You could also query the DBA_ERRORS
table (or ALL_ERRORS
or USER_ERRORS
depending on your privilege level) but that's not something you normally need to resort to.
Third, assuming the syntax errors get corrected, you're going to get a mutating table error if you use this logic. A row level trigger on table A (TPM_TRAININGPLAN
in this case) cannot query table A because the table may be in an inconsistent state. You can work around that, as Tim shows in his article, by creating a package with a collection, initializing that collection in a before statement trigger, populating the data in the collection in a row-level trigger, and then processing the modified rows in an after statement trigger. That's a decent amount of complexity to add to the system, however, since you'll have to manage multiple different objects.
Generally, you'd be better off implementing this logic as part of whatever API you use to manipulate the TPM_TRAININGPLAN
table. If that is a stored procedure, it makes much more sense to put the logic to update TPM_PROJECT
in that stored procedure rather than putting it in a trigger. It is notoriously painful to try to debug an application that has a lot of logic embedded in triggers because that makes it very difficult for developers to follow exactly what operations are being performed. Alternately, you could remove the TRAININGDELIVERYSTART
column from TPM_PROJECT
table and just compute the minimum start date at runtime.
Fourth, if your trigger fires on inserts, updates, and deletes, you can't simply reference :new
values. :new
is valid for inserts and updates but it is going to be NULL if you're doing a delete. :old
is valid for deletes and updates but is going to be NULL if you're doing an insert. That means that you probably need to have logic along the lines of (referencing Tim's package solution)
BEGIN
IF inserting
THEN
trigger_api.tab1_row_change(p_id => :new.projectid, p_action => 'INSERT');
ELSIF updating
THEN
trigger_api.tab1_row_change(p_id => :new.projectid, p_action => 'UPDATE');
ELSIF deleting
THEN
trigger_api.tab1_row_change(p_id => :old.projectid, p_action => 'DELETE');
END IF;
END;