I have a cursor for inserting employee data from temp table to main table. I have a scenario in which first it will check if temp table department id is exist in main department table; if DeptId does not exist then don't insert employee and update ERR_MSG column in temp table. I am handling exception inside if condition after INSERT statement, but it is giving me an error like
Encountered symbol EXCEPTION when expecting one of the following : begin,end,case,else......
sample code is as below:-
DECLARE
--var list
BEGIN
OPEN ltempCur For
-- here i am selecting cols from temp table in variables
LOOP
FETCH ltempCur
INTO
--all the declared variables here
EXIT
WHEN ltempCur %NOTFOUND;
BEGIN
--select statement for checking if employee record exist in table
IF(lExist == 0) --if emloyee record not exist
THEN
begin
--check if dept exist in dept table if not exist then i have assigned zero to deptid variable in NO_DATA_FOUND exception
end;
IF(vardeptid > 0) --if condition for which i have mentioned in description
--Insert statement for employee
EXCEPTION
WHEN OTHERS
THEN
--handling exp
COMMIT;
END;
END IF; -- dept id check if end
--end loop -- close cursor
In above code, if I remove deptid IF ELSE condition then it is working fine, but with that IF condition it is giving error
There is a single end if against two IF clauses. Probably, you have not ended the IF clause for variable lExists.
I'm trying to return the inserting row into a table of ROWTYPE in PL/SQL but I have the error:
ORA-00936: missing expression.
Table type declaration in package head:
TYPE t_retourResult IS TABLE OF RESULTATS%ROWTYPE;
And error at inserting in the package body:
PROCEDURE EncoderResultats(p_tResultats IN t_resultats, p_tAjoutes OUT t_retourResult, p_tErreurs OUT t_erreur)
IS
ExceptTResultats EXCEPTION;
i INTEGER;
BEGIN
IF(p_tResultats.COUNT = 0) THEN RAISE ExceptTResultats; END IF;
FORALL i IN INDICES OF p_tResultats SAVE EXCEPTIONS
INSERT INTO RESULATS VALUES p_tResultats(i) RETURNING * BULK COLLECT INTO p_tAjoutes;
COMMIT;
EXCEPTION
WHEN ExceptTResultats THEN RAISE_APPLICATION_ERROR(-20006,'Le tableau est vide, aucun resultat à ajouter');
WHEN OTHERS THEN RAISE;
END EncoderResultats;
there is a typo error in
INSERT INTO RESULATS VALUES p_tResultats(i) RETURNING * BULK COLLECT INTO p_tAjoutes;
it is not the table RESULATS but "RESULTATS"
moreover i guess you can't use "RETURNING * " , you have to specify all the column names as reported also here:
PL/SQL How return all attributes in ROW
I got this trigger, seems to be alright but i got the error :
Trigger :
CREATE OR REPLACE TRIGGER TRG_TABLE_BI
BEFORE INSERT
ON TABLE
FOR EACH ROW
DECLARE
CURSOR cur_list IS
SELECT emp, name, day, salary, id,phone
FROM TABLE NATURAL JOIN OTHERTABLE
WHERE emp = :NEW.emp AND name = :NEW.name AND id = :NEW.id;
curChoice cur_list%ROWTYPE;
BEGIN
OPEN cur_list;
LOOP
FETCH cur_list INTO curChoice;
EXIT WHEN cur_list%NOTFOUND;
dbms_output.put_line(curchoice.id);
dbms_output.put_line(curChoice.emp);
dbms_output.put_line(curchoice.name);
END LOOP;
CLOSE cur_list;
END;
/
I got those error :
PLS-00049: bad bind variable 'NEW.emp'
If i remove the ':' in the cursor declaration in my WHERE clause, i got a lot more error
Thank you.
Ok, i found the error, in my cursor declaration in the WEHRE clause, i had to remove
emp = :NEW.emp AND name = :NEW.name
because there's no such column in the table that im currently inserting.
Thank !
I've made a simple DVD store database. The DVD table has a column "status" which can be either 'FOR_RENT','FOR_SALE','RENTED',or 'SOLD'. I want to write a trigger to block any insertions into my RENTALS table if the status column in the DVD table is not set to 'FOR_RENT'.
Much of the documents I've looked at generally don't show example using values from two different tables so I'm a bit flummaxed.
This is what I believe has been my best attempt so far:
CREATE OR REPLACE TRIGGER RENTAL_UNAVAILABLE
BEFORE INSERT ON RENTAL;
FOR EACH ROW
WHEN (DVD.STATUS != 'FOR_RENT')
DECLARE
dvd_rented EXCEPTION;
PRAGMA EXCEPTION_INIT( dvd_rented, -20001 );
BEGIN
RAISE dvd_rented;
EXCEPTION
WHEN dvd_rented THEN
RAISE_APPLICATION_ERROR(-20001,'DVD has been rented');
END;
/
I'm getting this error:
ORA-00911: invalid character
Try this - I have not complied the code, but should be good. In case you see any compilation issues let me know and post schema on sqlfiddle.com
CREATE OR REPLACE TRIGGER rental_unavailable
BEFORE INSERT
ON rental
FOR EACH ROW
DECLARE
dvd_rented EXCEPTION;
PRAGMA EXCEPTION_INIT (dvd_rented, -20001);
n_count NUMBER (1);
BEGIN
SELECT COUNT (*)
INTO n_count
FROM dvd
WHERE dvd_id = :NEW.dvd_id AND dvd.status = 'FOR_RENT' AND ROWNUM < 2;
IF n_count > 0
THEN
RAISE dvd_rented;
END IF;
EXCEPTION
WHEN dvd_rented
THEN
raise_application_error (-20001, 'DVD has been rented');
END;
I am trying to write a trigger when I am receiving this error, it the first I encounter such error, and none of my searches lead to my case, kindly check
this is the trigger :
create or replace trigger TR_new_student
for insert on Students
compound trigger
IDs students.ID%type;
ID_user students.ID_u%type;
password users.password%type;
cand_m1 master.ID_master%type;
cand_m2 master.ID_master%type;
cand_m3 master.ID_master%type;
cand_password_m1 users.password%tyPe;
cand_password_m2 users.password%type;
cand_password_m3 users.password%type;
cand_password_m4 users.password%type;
username users.username%type;
type class_type is TABLE OF class%rowtype index by PLS_integer;
class_tab class_type;
part1 varchar2(12);
before each row
is
begin
:new.classes_accepte:='N';
:new.n_download:=0;
:new.n_msg_adm:=0;
:new.n_msg_res:=0;
:new.date_last_download:=sysdate;
:new.date_last_m_a:=sysdate;
:new.date_last_m_r:=sysdate;
:new.year_insc:=get_annee_scolaire;
:new.current_year:=get_annee_scolaire;
select ID_M1,ID_M2,ID_M3,password_m1,password_m2,password_m3,password_m4
into cand_m1,cand_m2,cand_m3,cand_password_m1,cand_password_m2,cand_password_m3,cand_password_m4
from candidate c
where c.ID_c=:new.ID_c and c.year=:new.year_insc;
password :=
CASE
when cand_M1=:new.current_master then cand_password_m1
when cand_M2=:new.current_master then cand_password_m2
when cand_M3=:new.current_master then cand_password_m3
else cand_password_m4
end;
if password != :new.first_pass then raise_application_error(-20003,'Le mot de passe n''est pas valide');
end if;
SELECT SUBSTR(:new.Fname, 1, 12) into part1 FROM DUAL;
username:=part1||TO_CHAR(:new.ID);
ID_user:=ID_u_seq.currval;
:new.ID_u:=ID_user;
ID_s:=ID_seq.nextval;
:new.ID:=ID_s;
insert
into users
values (ID_user,username,password,1);
insert
into inscriptions (year,date_insc,old_new,ID,master_ID,succeeded,password)
values (:new.year_insc,sysdate,'N',:new.ID,:new.current_master,:new.current_master,'P',password);
select *
BULK COLLECT INTO class_tab
from class d
where d.ID_master=:new.current_master and d.optionnel='N' and d.available='Y';
forall i in indices of class_tab
insert into Grades
values (class_tab(i).ID_class,:new.current_master,:new.ID,:new.year_insc,class_tab(i).graded,class_tab(i).credit,class_tab(i).semestre,class_tab(i).partial_flag,class_tab(i).final_1_flag,class_tab(i).project_flag,class_tab(i).final_2_flag,class_tab(i).partial_percent,class_tab(i).final_percent,class_tab(i).project_percent,'N','N','N','N','N',0,0,0,0,0,sysdate,:new.ID_u,'P',class_tab(i).description);
end before each row;
after statement
is
begin
execute immediate 'Create or replace view vue_stu'||IDs||'
as select province,circonscription,city,region,fam_status,cur_province,cur_cir,cur_region,cur_city,street,property,floor,phone,picture
from students
where ID_u='||ID_user||'';
execute immediate 'Grant update on vue_stu'||IDs||' to C##'||username||'';
end after statement;
end TR_new_student;
/
and this is the error I am receiving :
ORA-01775: looping chain of synonyms
can anyone tell me the possible source of this error or how I can fix it ?
thank you in advance :)
You should execute the following statement before compiling the trigger:
alter session set events '1775 trace name errorstack level 3;
Then compile the trigger. This will create a trace file. Provide a link to the created trace file.