Question:
fl_schedule(flno, departs, dtime, arrives, atime, price).
Create a trigger to allow insertion or updation only if Flight number CX7520 is scheduled on Tuesday, Friday and Sunday.
CREATE OR REPLACE TRIGGER flightsch_day
BEFORE INSERT OR UPDATE ON fl_schedule
FOR EACH ROW
WHEN (NEW.flno LIKE 'CX7520')
DECLARE
day NUMBER;
BEGIN
day:=EXTRACT(weekday FROM :NEW.departs);
IF day NOT IN(0,2,5) THEN
RAISE_APPLICATION_ERROR(-20000,'Flight number CX7520 can be scheduled only on Tuesday, Friday and Sunday.');
END IF;
END;
/
ERRORS:
SQL> SHOW ERRORS;
Errors for TRIGGER FLIGHTSCH_DAY:
LINE/COL ERROR
-------- -----------------------------------------------------------------
4/10 PLS-00122: FROM as separator is allowed only with specific
built-in functions
In order to be able to use WHEN (NEW.flno = 'CX7520') after FOR EACH ROW, UPDATE OF flno is needed for individual column flno
CREATE OR REPLACE TRIGGER flightsch_day
BEFORE INSERT OR UPDATE OF flno ON fl_schedule
FOR EACH ROW
WHEN (NEW.flno = 'CX7520')
DECLARE
BEGIN
IF TO_CHAR(:NEW.departs,'Dy','NLS_DATE_LANGUAGE=English') NOT IN ('Tue','Fri','Sun') THEN
RAISE_APPLICATION_ERROR(-20000,'Flight number CX7520 can be scheduled only on Tuesday, Friday and Sunday.');
END IF;
END;
/
or without that WHEN.. clause, take :NEW.flno = 'CX7520' into IF Statement :
CREATE OR REPLACE TRIGGER flightsch_day
BEFORE INSERT OR UPDATE ON fl_schedule
FOR EACH ROW
DECLARE
BEGIN
IF NOT ( TO_CHAR(:NEW.departs,'Dy','NLS_DATE_LANGUAGE=English') IN ('Tue','Fri','Sun')
AND :NEW.flno = 'CX7520' ) THEN
RAISE_APPLICATION_ERROR(-20000,'Flight number CX7520 can be scheduled only on Tuesday, Friday and Sunday.');
END IF;
END;
/
use day abbreviations containing NLS_DATE_LANGUAGE option.
Otherwise you can meet the unexpected situations.
displayed error stems from use of weekday within EXTRACT() function where use of day, month, year allowed for a date type variable, also hour, minute, second ..etc. if it's a datetime type variable is allowed, but not weekday
Related
I'm setting up a win auto job to accrue paid time off.
However, for personal time they only get a lump sum every year.
So I'm working on a pl/sql statement to check the date, but I can't get it to work.
I'm not sure what I'm doing wrong!!!
IF to_char(sysdate, 'MM/dd') = '01/01' THEN
PTO.personal_time := 8;
END IF;
update: to clarify. I want to check the date and if it is January first, to update the amount of personal time to 8 hours. I'm not getting any errors, but the amount of personal time isn't changing. There is no roll over and everyone gets one personal day, so i just set in on January 1st.
TABLE is a keyword and you cannot use it as a variable; however, if you replace table with the name of your variable then your code works perfectly (assuming that the variables of the appropriate names/types already exists):
DECLARE
-- declare a type which has a field names "field"
TYPE item_type IS RECORD(
field NUMBER
);
-- declare an "item" variable
item item_type;
BEGIN
-- start of your code
IF to_char(sysdate, 'MM/dd') = '04/25' THEN
item.field := 8;
END IF;
-- end of your code
DBMS_OUTPUT.PUT_LINE( item.field );
END;
/
which outputs:
8
db<>fiddle here
I am trying to create job which executes every monday on 04:00 with the script
declare
job number;
begin
sys.dbms_job.submit( job,
'CALC_LAST_WEEK_STAT();',
to_date('03-07-2017 04:00:00', 'dd-mm-yyyy hh24:mi:ss'),
trunc('NEXT_DAY(TRUNC(SYSDATE), "MONDAY") + 4/24'),'dd-mm-yyyy hh24:mi:ss');
commit;
end;
/
but i have error PLS-00306: wrong number or types of arguments in call to 'SUBMIT'
If you have a look at the documentation for DBMS_JOB.SUBMIT() you will see that the datatype for interval is VARCHAR2. You are passing a date whereas SUBMIT() expects the formula for working out the time of the next run.
So that would be
q'[(NEXT_DAY(TRUNC(SYSDATE), 'MONDAY') + 4/24)]'
I'm trying to create a trigger which would prevent insertions, updates and deletions if done outside office hours(i.e, other than 8-18 hours or sundays)
here is my code:
CREATE OR REPLACE TRIGGER HOLIDAY
BEFORE DELETE OR INSERT OR UPDATE ON DEPT FOR EACH ROW
BEGIN
IF ((EXTRACT(DAY FROM SYSDATE)='SUNDAY') OR (EXTRACT(HOUR FROM LOCALTIMESTAMP) NOT BETWEEN 8 AND 18)) THEN
RAISE_APPLICATION_ERROR(-20001,'ILLEGAL OPERATION - OUT OF OFFICE HOURS OR HOLIDAY!');
END IF ;
END;
/
the trigger was created.
Today is sunday and when i try to insert a row, the application error is not raise, instead, what i get is:
SQL> #/home/divya/A43.SQL
Trigger created.
SQL> DELETE FROM DEPT WHERE D_NO = 'D3' ;
DELETE FROM DEPT WHERE D_NO = 'D3'
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
ORA-06512: at "DIVYA12345.HOLIDAY", line 2
ORA-04088: error during execution of trigger 'DIVYA12345.HOLIDAY'
Can someeone please tell me exactly what is the error? show errors displays - no errors as output. Any help is highly appreciated. thanks in advance.
You get the error because EXTRACT(DAY FROM SYSDATE) returns the number of the day in month, not its name. To retrieve the name, you can use TO_CHAR(SYSDATE, 'DAY') instead, or to_char(sysdate,'fmDY', 'nls_date_language = ENGLISH') as suggested in the comments:
CREATE OR REPLACE TRIGGER HOLIDAY
BEFORE DELETE OR INSERT OR UPDATE ON DEPT FOR EACH ROW
BEGIN
IF (TO_CHAR(sysdate,'fmDY', 'nls_date_language = ENGLISH')='SUNDAY') OR (EXTRACT(HOUR FROM LOCALTIMESTAMP) NOT BETWEEN 8 AND 18)) THEN
RAISE_APPLICATION_ERROR(-20001,'ILLEGAL OPERATION - OUT OF OFFICE HOURS OR HOLIDAY!');
END IF ;
END;
/
I have employee table in oracle.I want to create a trigger that will avoid insertion of data on sun day. please tell me the program?following program not working.
Here's an example trigger that checks for week day and, if day is sunday (7), throws an user defined exception ORA-20000:
CREATE OR REPLACE TRIGGER trg_sunday
BEFORE INSERT ON employee
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
BEGIN
IF TO_CHAR(SYSDATE, 'D') = '7' THEN
RAISE_APPLICATION_ERROR(-20000, 'Cannot insert record on sunday');
END IF;
END;
Please check which number identifies sunday, it depends on the local NLS settings of the database. Here in Italy (NLS_TERRITORY='ITALY') Sunday is identified by 7 but with different database NLS setting the number may vary.
You may take a look at Day of week (1-7) and NLS settings
The trigger remains the same but the query goes like below:
to check whats day today"
select to_char(to_date('08/08/2016','dd/mm/yyyy'), 'DY'),TO_CHAR(SYSDATE, 'D') from dual;
To check next sunday:
select to_char(to_date('14/08/2016','dd/mm/yyyy'), 'DY'),TO_CHAR(to_date('14/08/2016','dd/mm/yyyy'), 'D') from dual;
The correct code should be:
CREATE OR REPLACE TRIGGER trg_sunday
BEFORE INSERT ON employee
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
BEGIN
IF TO_CHAR(SYSDATE, 'D') = '1' THEN ---Should be 1 rather than 7
RAISE_APPLICATION_ERROR(-20000, 'Cannot insert record on sunday');
END IF;
END;
You can create your trigger as shown in below code snippet.
CREATE OR REPLACE TRIGGER sunday_prevent
BEFORE INSERT ON account
FOR EACH ROW
Begin
IF TO_CHAR(SYSDATE,'day')='sunday' then
raise_application_error(-20000,'Today is Sunday so you not perform any transaction');
END IF;
END;
/
I have a trigger which is sending data from a table to another table in another database. all s working fine.
The prob is that there is a new concept of END DATE, in which, if END DATE is present for a person, the row should reach the other table on that particular date..
eg.: if someones end date is 31st august, it should go on that day only, but ofcourse, my trigger is firing on event change (when enddate is set to 31st august)..
Could you please suggest me what I can do to SET the row to go on ENDDATE.?
It doesn't sound like you don't want a trigger. It sounds like you want a job. For example, if you create a procedure that transfers all the rows whose end_date is today
CREATE OR REPLACE PROCEDURE move_rows_with_end_date(
p_end_date IN DATE DEFAULT trunc(SYSDATE)
)
AS
BEGIN
INSERT INTO table_name#remote_database( <<list of columns>> )
SELECT <<list of columns>>
FROM table_name
WHERE end_date = trunc(sysdate);
END;
Then you can create a job that runs the procedure every day at midnight
DECLARE
l_jobno PLS_INTEGER;
BEGIN
dbms_job.submit( l_jobno,
'BEGIN move_rows_with_end_date; END;',
trunc(sysdate+1),
'trunc(sysdate+1)' );
commit;
END;