How can I get this trigger to prevent the insert where the advance is not greater than 0 or less than 100? Thanks.
DROP TRIGGER CheckAdvance;
CREATE OR REPLACE TRIGGER CheckAdvance
BEFORE INSERT OR UPDATE OF advance ON titles
FOR EACH ROW
WHEN (new.advance<0 OR new.advance>100)
BEGIN
dbms_output.put_line('Advance is Invalid.');
END;
DELIMITER // CREATE TRIGGER yourTriggerName BEFORE INSERT ON yourTableName FOR EACH ROW BEGIN yourCondition THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'anyMessageToEndUser'; END // DELIMITER ; Now, create a trigger that would prevent to insert a record in the table on some condition.
An INSTEAD OF trigger is an SQL trigger that is processed “instead of” an SQL UPDATE, DELETE or INSERT statement. Unlike SQL BEFORE and AFTER triggers, an INSTEAD OF trigger can be defined only on a view, not a table.
The only way for a trigger on a table to prevent an INSERT operation from completing is to throw an error. Create an instead of trigger on that view that only does an INSERT on the table if you want the row to be persisted. Otherwise, the trigger would do nothing.
"it was a class question."
I had a chat with a university lecturer who taught PL/SQL after I gave a presentation at a conference. My talk was on PL/SQL good practice; one of my slides simply said "Don't use triggers". The lecturer told me he finds such advice difficult to reconcile with the needs of the curriculum. They have to teach their students all the syntax but he admitted that often they set tasks which demanded solutions we wouldn't use when writing software professionally.
This is such a question. The correct approach is to use a check constraint, as Gordon's answer shows. Constraints are more efficient, and idiomatic too. But your teacher wants you to write a trigger, so here is your code, corrected.
CREATE OR REPLACE TRIGGER CheckAdvance
BEFORE INSERT OR UPDATE OF advance ON titles
FOR EACH ROW
BEGIN
IF :new.advance < 0
THEN
raise_application_error(-20000
, 'Advance cannot be less than zero');
ELSIF :new.advance > 100
THEN
raise_application_error(-20001
, 'Advance cannot be greater than one hundred.');
END IF;
END;
Points to note:
@yadipp reminded me that the WHEN clause used in the Seeker's question is valid syntax, so belatedly I'm extending my solution to show how that would look. The most important thing to note is that NEW and OLD aren't treated as bind variables and so don't take a :
.
CREATE OR REPLACE TRIGGER CheckAdvance
BEFORE INSERT OR UPDATE OF advance ON titles
FOR EACH ROW
WHEN (new.advance < 0 OR new.advance > 100)
BEGIN
raise_application_error(-20000
, 'Advance cannot be less than zero or greater than one hundred.');
END;
(And I tweaked my original solution to show one reason to use IF in the trigger body: to handle different conditions differently.)
You shouldn't use a trigger for this. Oracle (and SQL in general) supports check constraints:
alter table titles
add constraint chk_titles_advance check (advance > 0 and advance <= 100);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With