I want to use an if statement inside trigger but the value if comparison will come from an other select statement.
I have done the following:
create or replace
Trigger MYTRIGGER
After Insert On Table1
Referencing Old As "OLD" New As "NEW"
For Each Row
Begin
Declare Counter Int;
Select Count(*) From Table2 Where Table2."Email" = :New.U_MAIL Into Counter;
IF Counter < 1 THEN
//INSERT Statement here...
END IF;
End;
My logic is simple, if same email user exists, insert will not work.
Above code did not work. How can we do this?
A few syntax errors. Would be closer to something like this:
create or replace
Trigger MYTRIGGER
After Insert On Table1
Referencing Old As "OLD" New As "NEW"
For Each Row
DECLARE
v_count NUMBER;
BEGIN
SELECT COUNT(*)
INTO v_count
FROM Table2
WHERE Email = :New.U_MAIL
;
IF v_count > 0
THEN
RAISE_APPLICATION_ERROR(-20000, 'Not inserted...');
END IF;
END;
Your approach is wrong. Referential integrity should not be made using triggers, it just cannot work as required. See example:
Connected to Oracle Database 12c Enterprise Edition Release 12.1.0.2.0
Connected as test@soft12c1
SQL> create table mail_1 (email varchar2(100));
Table created
SQL> create table mail_2 (email varchar2(100));
Table created
SQL> create trigger mail_1_check
2 before insert on mail_1
3 for each row
4 declare
5 cnt integer;
6 begin
7 select count(*) into cnt from mail_2 where email = :new.email;
8 if cnt > 0 then
9 raise_application_error(-20100, 'Email already exists');
10 end if;
11 end;
12 /
Trigger created
SQL> insert into mail_2 values ('president@gov.us');
1 row inserted
SQL> insert into mail_1 values ('king@kingdom.en');
1 row inserted
SQL> insert into mail_1 values ('president@gov.us');
ORA-20100: Email already exists
ORA-06512: at "TEST.MAIL_1_CHECK", line 6
ORA-04088: error during execution of trigger 'TEST.MAIL_1_CHECK'
It looks like trigger works right, but it's not true. See what happens when several users will works simultaneously.
-- First user in his session
SQL> insert into mail_2 values ('dictator@country.by');
1 row inserted
-- Second user in his session
SQL> insert into mail_1 values ('dictator@country.by');
1 row inserted
-- First user is his session
SQL> commit;
Commit complete
-- Second user is his session
SQL> commit;
Commit complete
-- Any user in any session
SQL> select * from mail_1 natural join mail_2;
EMAIL
--------------------------------------------------------------------------------
dictator@country.by
If using triggers for this task, you should serialize any attempts to use this data, say, execute LOCK TABLE IN EXCLUSIVE MODE unless commit. Generally it's a bad decision. For this concrete task you can use much better approach:
Connected to Oracle Database 12c Enterprise Edition Release 12.1.0.2.0
Connected as test@soft12c1
SQL> create table mail_1_2nd(email varchar2(100));
Table created
SQL> create table mail_2_2nd(email varchar2(100));
Table created
SQL> create materialized view mail_check
2 refresh complete on commit
3 as
4 select 1/0 data from mail_1_2nd natural join mail_2_2nd;
Materialized view created
OK. Let's see, what if we try to use same email:
-- First user in his session
SQL> insert into mail_1_2nd values ('dictator@gov.us');
1 row inserted
-- Second user in his session
SQL> insert into mail_2_2nd values ('dictator@gov.us');
1 row inserted
SQL> commit;
Commit complete
-- First user in his session
SQL> commit;
ORA-12008: error in materialized view refresh path
ORA-01476: divisor is equal to zero
SQL> select * from mail_1_2nd natural join mail_2_2nd;
EMAIL
--------------------------------------------------------------------------------
no rows selected
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.