Oracle Trigger create with compilation errors - sql

I wrote the below trigger to prevent users from allocating a Class to a Session if the Class Date does not match the day of the week the Session is on.
CREATE OR REPLACE TRIGGER trig_alternative_classDate
AFTER INSERT OR UPDATE ON ALTERNATIVE
FOR EACH ROW
DECLARE
classdate CHAR;
sessionday VARCHAR;
BEGIN
SELECT to_char(to_date(class.class_date), 'Day') INTO classdate, sessions.day INTO sessionday
FROM SESSIONS, CLASS, DUAL, LOCATION, ALTERNATIVE
WHERE class.class_id = alternative.class_id
AND alternative.location_id = location.location_id
AND sessions.location_id = location.location_id;
IF sessions.day != to_char(to_date(class.class_date), 'Day')
THEN raise_application_error(-20999,'Invalid Class Date - Class Date does not match Session Day');
END IF;
END;
/
However I get an error message when I run the trigger
Warning: Trigger created with compilation errors.
SQL> show error trigger trig_alternative_classDate
Errors for TRIGGER TRIG_ALTERNATIVE_CLASSDATE:
LINE/COL ERROR
-------- -----------------------------------------------------------------
5/2 PL/SQL: SQL Statement ignored
5/80 PL/SQL: ORA-00923: FROM keyword not found where expected
Could someone please help?

Remove second INTO - only one INTO is needed:
INTO classdate, sessions.day INTO sessionday

Related

Why is "ADD_YEARS" an invalid identifier?

I'm trying to use SQL's "ADD_YEARS" in an Oracle PLSQL Procedure.
However, (assuming it's actually to blame) it has an error on compilation: "invalid identifier".
I suspect that this is because the ADD_YEARS is something out of SQL, and not PLSQL. They don't seem to like each other. The only way I can think of doing this is to create a local variable and assign it the result I'd normally have gotten from ADD_YEARS. However, when I tried I couldn't figure out how to actually...assign some value to that. There's SELECT INTO but that makes 0 sense in this case.
-- If in good standing, extend membership 1 year.
-- If not but within grace (6 months), extend to 1 year from today.
-- Otherwise, explain renewal involves penalty. If no ID, print message.
CREATE OR REPLACE PROCEDURE renew(id1 IN member.id%type) IS
temp1 member.expr_date%type;
BEGIN
SELECT expr_date INTO temp1 FROM member WHERE id = id1;
IF temp1 > CURRENT_DATE THEN
UPDATE member
SET expr_date = ADD_YEARS(expr_date, 1)
WHERE id = id1;
ELSIF ADD_MONTHS(temp1, 6) > CURRENT_DATE THEN
UPDATE member
SET expr_date = ADD_YEARS(CURRENT_DATE, 1)
WHERE id = id1;
ELSE
dbms_output.put_line('Renewal will incur a penalty!');
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('That ID does not exist as a member!');
END;
/
show errors
Here's the error I'm getting:
Errors for PROCEDURE RENEW:
LINE/COL ERROR
-------- -----------------------------------------------------------------
7/3 PL/SQL: SQL Statement ignored
8/19 PL/SQL: ORA-00904: "ADD_YEARS": invalid identifier
11/3 PL/SQL: SQL Statement ignored
12/19 PL/SQL: ORA-00904: "ADD_YEARS": invalid identifier
Thanks much for any help! I'm still very new to SQL and PL/SQL. Getting over some of its quirks has been difficult.
As mentioned in my comments, you cannot use ADD_YEARS since in Oracle nothing exist as ADD_YEARS. You can inturn use ADD_MONTHS or INTERVAL clause.
So you can modify your block update statement as :
SET expr_date = ADD_YEARS(expr_date, 1)
1) SET expr_date = ADD_MONTHS(expr_date, 12)
Or
2) SET expr_date = expr_date + interval '1' YEAR

Can't fix Error: PL/SQL Statement ignored

I've just started working with Triggers. While trying to compile the next code fragment errors are listed in the log, like so: "Error(2,3): PL/SQL: SQL Statement ignored" and "Error(2,7): PL/SQL: ORA-00922: missing or invalid option".
I don't understand the problem. Can anybody help?
CREATE OR REPLACE TRIGGER CONT_VIG
BEFORE INSERT ON CONTRACTS
FOR EACH ROW
WHEN (OLD.CLIENTID = NEW.CLIENTID AND OLD.ENDDATE > NEW.STARTDATE)
BEGIN
SET (OLD.enddate = :NEW.startdate-1);
END;
look this this-oracle and this-stackoverflow
try this:
CREATE TRIGGER hr.salary_check
BEFORE INSERT OR UPDATE OF salary, job_id ON hr.employees
FOR EACH ROW
WHEN (new.job_id <> 'AD_VP')
pl/sql_block
You can't change OLD value...
replace
SET (OLD.enddate = :NEW.startdate-1);
with for example :
:NEW.startdate := sysdate ;
(I removed SET because I don't see the usefulness)

Create a trigger

Create a trigger called NewEntry, that will not allow a result to be inserted into the student exam table if it is less than zero. In your query display a suitable message if the result is less than zero and supply code to test the trigger.
This is what I have done, but I keep getting
warning : trrigger created with compilation errors.
This is my code, please help!
CREATE OR REPLACE TRIGGER NewEntry
AFTER INSERT OR UPDATE ON Assignment2.Student_Exam
FOR EACH ROW
DECLARE
Results NUMBER;
BEGIN
IF(:NEW.Results < '0')
THEN
RAISE_APPLICATION_ERROR
(-20700,'Student's result cannot be less-than ZERO..Enter valid Results':);
ENDIF;
END;
/
END IF, not ENDIF. Also as Jeremy C mentions above you need to create the trigger as BEFORE INSERT OR UPDATE
you listen the other answers but one more thing ,
you must focus on :NEW.Results this is the thing.
There are two errors: Firstly it is 'END IF' not ENDIF, secondly you have apostrophe's in your message.
The correct code is:
CREATE OR REPLACE TRIGGER NewEntry
AFTER INSERT OR UPDATE ON Assignment2.Student_Exam
FOR EACH ROW
DECLARE
Results NUMBER;
BEGIN
IF(:NEW.Results < '0')
THEN
RAISE_APPLICATION_ERROR
(-20700, 'students result cannot be less-than ZERO..Enter valid Results:');
END IF;
END;
/
As others have said you could have de-bugged this yourself by typing show errors; This would have given you the answer e.g.
SQL> show errors;
Errors for TRIGGER NEWENTRY:
LINE/COL ERROR
-------------------------------------------------------------------------
7/18 PLS-00103: Encountered the symbol "S" when expecting one of the
following:
) , * & = - + < / > at in is mod remainder not rem =>
<an exponent (**)> <> or != or ~= >= <= <> and or like like2
like4 likec between || multiset member submultiset
edit: In reply to Ersin - If it was New.Results then you would get a bind error e.g.
SQL> show errors;
Errors for TRIGGER NEWENTRY:
LINE/COL ERROR
-------- -----------------------------------------------------------------
4/4 PLS-00049: bad bind variable 'NEW.RESULTS'
SQL>
This will be a result of 'RESULTS' not being a column in Student_Exam, which I presume does exist given the rest of the statement.

SQL PLUS Trigger compilation errors

I am trying to create a trigger to calculate a derived attribute on each insert command. However I am getting compilation errors, I dont know where is the problem.
CREATE OR REPLACE TRIGGER NewTrigger
BEFORE INSERT
ON Dates FOR EACH ROW
BEGIN
SET :NEW.difference := :NEW.date1 - :NEW.date2;
END;
Show errors shows me this information:
LINE/COL ERROR
-------- -----------------------------------------------------------------
1/7 PL/SQL: SQL Statement ignored
1/11 PL/SQL: ORA-00922: missing or invalid option
It's not the trigger, it's the data type. If you substract a date from another date, the result is an interval, not another date:
CREATE TABLE dates (date1 DATE, date2 DATE, datediff DATE, numdiff NUMBER);
INSERT INTO dates (date1, date2) VALUES (sysdate, sysdate-1);
UPDATE dates SET numdiff = date1 - date2;
1 rows updated
UPDATE dates SET datediff = date1 - date2;
SQL Error: ORA-00932: inconsistent datatypes: expected DATE got DATE JULIAN
So, if the trigger stores the interval in a number, it compiles:
CREATE OR REPLACE TRIGGER newtriggernum
BEFORE INSERT ON dates FOR EACH ROW
BEGIN
:new.numdiff := :new.date1 - :new.date2;
END;
/
TRIGGER NEWTRIGGERNUM compiled
and if it stores the interval in a date, it doesn't:
CREATE OR REPLACE TRIGGER newtriggerdate
BEFORE INSERT ON dates FOR EACH ROW
BEGIN
:new.datediff := :new.date1 - :new.date2;
END;
/
Error(2,11): PL/SQL: ORA-00922: missing or invalid option
CREATE OR REPLACE TRIGGER NewTrigger
BEFORE INSERT ON Dates FOR EACH ROW
BEGIN
:NEW.difference := :NEW.date1 - :NEW.date2;
End;
/

Oracle trigger failed -ORA-04098

I have a table for which i have written a trigger:
CREATE OR REPLACE TRIGGER ac01_control_trigg
AFTER INSERT ON ac1_control_test
FOR EACH ROW
DECLARE
BEGIN
IF :NEW.cur_pgm_name = 'LSN'
AND :NEW.nxt_pgm_name ='MD'
AND :NEW.file_status='RD' THEN
INSERT INTO ac1_control_test
(FILE_NAME, FILE_PATH,FILE_STATUS,CUR_PGM_NAME,NXT_PGM_NAME)
VALUES
(:NEW.FILE_NAME, :NEW.FILE_PATH,:NEW.FILE_STATUS,:NEW.CUR_PGM_NAME,'MD_MPS');
END IF;
END ac01_control_trigg;
when i am trying to insert into the table i am getting an error below!
ORA-04098: trigger 'CNGDB18.AC01_CONTROL_TRIGG' is invalid and failed re-validation
could anybody please help?
also when i compile the trigger in Toad,i am getting compile errors as below:
LINE/COL ERROR
-------- -----------------------------------------------------------------
3/65 PLS-00049: bad bind variable 'NEW_FILE_STATUS'
but what is the wrong with this?
and what does this error mean?
EDIT: Now that we see the message, the solution is easy :)
Use :NEW.file_status='RD' instead of:new_file_status='RD'
Your trigger object is invalid (there is a problem with the code).
Test this with:
SELECT object_name, status
FROM user_objects
WHERE object_name = 'AC1_CONTROL_TRIGG';
Should return:AC1_CONTROL_TRIGG INVALID
You can try the following in SQL*Plus to get a description of the error:
ALTER TRIGGER ac1_control_trigg COMPILE;
SHOW ERROR TRIGGER ac1_control_trigg;
Using TOAD, you can just type these two lines into an editor, select them and use Editor>Execute SQL via SQL*Plus.