问题
I have account table as this--
create table account
(
acct_id int,
cust_id int,
cust_name varchar(20)
)
insert into account values(1,20,'Mark');
insert into account values(2,23,'Tom');
insert into account values(3,24,'Jim');
I want to create a trigger which will ensure that no records can be inserted or update in account table having acct_id as 2 and cust_id as 23.
My code is --
create trigger tri_account
before insert or update
on account
for each row
begin
IF (:new.acct_id == 2 and :new.cust_id == 23) THEN
DBMS_OUTPUT.PUT_LINE('No insertion with id 2 and 23.');
rollback;
END IF;
end;
so this trigger is created , but with compilation error. now when I insert any record with acct_id as 2 and cust_id as 23,it doesent allow. But I get an error saying ORA-04098: trigger 'OPS$0924769.TRI_ACCOUNT' is invalid and failed re-validation
I don't understand this.I also want to show a message that dis insertion is not possible. please Help...
回答1:
- The equality operator in Oracle is
=
, not==
. - You cannot commit or rollback in a trigger. You can throw an exception which causes the triggering statement to fail and to be rolled back (though the existing transaction will not necessarily be rolled back).
- It does not appear that this trigger compiled successfully when you created it. If you are using SQL*Plus, you can type
show errors
after creating a PL/SQL object to see the compilation errors. - You should never write code that depends on the caller being able to see the output from
DBMS_OUTPUT
. Most applications will not so most applications would have no idea that the DML operation failed if your trigger simply tries to write to theDBMS_OUTPUT
buffer.
Putting those items together, you can write something like
create trigger tri_account
before insert or update
on account
for each row
begin
IF (:new.acct_id = 2 and :new.cust_id = 23) THEN
raise_application_error( -20001, 'No insertion with id 2 and 23.');
END IF;
end;
回答2:
A trigger is more flexible, but you can also accomplish this through the use of a CHECK CONSTRAINT:
ALTER TABLE account ADD CONSTRAINT check_account CHECK ( acct_id != 2 OR cust_id != 23 )
ENABLE NONVALIDATE;
The NONVALIDATE clause will ensure that the check constraint does not attempt to validate existing data, though it will validate all future data.
Hope this helps.
回答3:
IF (:new.acct_id = 2 and :new.cust_id = 23) THEN
must be OR
, not and
.
回答4:
While using conditional checks you don't need to use colons (:
). This will always cause errors.
Note: Exclude the colon only in cases where condition checking is performed.
来源:https://stackoverflow.com/questions/9654623/how-to-create-a-trigger-in-oracle-which-will-restrict-insertion-and-update-queri