PLS-00103: Encountered the symbol "B" when expecting one of the following - oracle

BEGIN
DBMS_SCHEDULER.CREATE_JOB(
JOB_NAME => 'BillsDueCheck',
JOB_TYPE => 'PLSQL_BLOCK',
JOB_ACTION => 'BEGIN
UPDATE Customer C
SET C.Standing = 'B'
WHERE C.CustomerID IN (
SELECT B.CUSTOMERID
FROM Bill B
WHERE (BillDate + 60) < SYSDATE);
END;',
START_DATE => SYSTIMESTAMP,
REPEAT_INTERVAL => 'FREQ=DAILY'
END_DATE => NULL,
ENABLED => TRUE,
COMMENTS => 'Checks if the bill is overdue'
);
END;
The error occurs at the SET line I think I must be doing something wrong further up but I'm not sure.
I have tried running the job action by it's self and it works fine.

You must double your quotes around your 'B' otherwise oracle will think your string is terminated and try to interpret the B as a command.
BEGIN
DBMS_SCHEDULER.CREATE_JOB(
JOB_NAME => 'BillsDueCheck',
JOB_TYPE => 'PLSQL_BLOCK',
JOB_ACTION => 'BEGIN
UPDATE Customer C
SET C.Standing = ''B''
WHERE C.CustomerID IN (
SELECT B.CUSTOMERID
FROM Bill B
WHERE (BillDate + 60) < SYSDATE);
END;',
START_DATE => SYSTIMESTAMP,
REPEAT_INTERVAL => 'FREQ=DAILY'
END_DATE => NULL,
ENABLED => TRUE,
COMMENTS => 'Checks if the bill is overdue'
);
END;

Related

Scheduler job on Oracle does not run every second

I have a specific scheduler job in Oracle that needs to be run every second.
I tried to create this (using a procedure):
begin
sys.dbms_scheduler.create_job(job_name => 'WBC6_PUBLIC.TESTE',
job_type => 'STORED_PROCEDURE',
job_action => 'proc_insert_data',
start_date => to_date('19-02-2020 09:00:00', 'dd-mm-yyyy hh24:mi:ss'),
repeat_interval => 'Freq=Secondly;Interval=1',
end_date => to_date(null),
job_class => 'DEFAULT_JOB_CLASS',
enabled => true,
auto_drop => false,
comments => '');
end;
/
And this (using PLSQL_BLOCK):
begin
sys.dbms_scheduler.create_job(job_name => 'WBC6_PUBLIC.TESTE',
job_type => 'PLSQL_BLOCK',
job_action => 'insert into my_table (date) values (sysdate);',
start_date => to_date('19-02-2020 09:00:00', 'dd-mm-yyyy hh24:mi:ss'),
repeat_interval => 'Freq=Secondly;Interval=1',
end_date => to_date(null),
job_class => 'DEFAULT_JOB_CLASS',
enabled => true,
auto_drop => false,
comments => '');
end;
/
But the result is the same, the job runs every ~ 4 seconds.
Is there a parameter or something I can do to run every second?
I've tried something like this before and if the procedure takes or could take more than the interval, then it is impossible. Al alternative is to run the code in a continuous loop with some kind of stop mechanism inbuilt (e.g. check a stop_table.stop_column for a "stop" condition). For example:
BEGIN
LOOP
proc_insert_data; /* run your insert */
sys.DBMS_SESSION.sleep(1); /* Pause for 1 second. */
stop_condition := stop_condition + 1;
EXIT WHEN stop_condition = 900; /* exit after 15 min OR some other mechanism of your choice */
END LOOP;
END;
/

Create a Job in ORACLE

I have to create a job periodically.
But firstly I have create a simply job to learn how to create jobs in oracle, because is the first time I use a job.
It runs at systimestamp, but the job doesn't execute.
create or replace procedure job_test
is
begin
update table_a set value_user = 'JOB_EXECUTED' where id = 1;
commit;
end;
/
Then the scheduler job
begin
dbms_scheduler.create_job(
job_name => 'test_job_A',
job_type => 'stored_procedure',
job_action => 'job_test',
start_date = SYSTIMESTAMP,
enabled => true
);
end;
/
Then I consult the column value_user and it hasn't been updated.
select * from table_A where id = 1;
Can anyone explain me what I am missing.
create table user_count (
number_of_users NUMBER(4),
time_of_day TIMESTAMP
);
CREATE OR REPLACE PROCEDURE insert_user_count AS
v_user_count NUMBER(4);
BEGIN
SELECT count(*)
INTO v_user_count
FROM v$session
WHERE username IS NOT NULL;
INSERT INTO user_count
VALUES (v_user_count, systimestamp);
commit;
END insert_user_count;
BEGIN
DBMS_SCHEDULER.CREATE_PROGRAM (
program_name => 'PROG_INSERT_USER_COUNT',
program_action => 'INSERT_USER_COUNT',
program_type => 'STORED_PROCEDURE');
END;
BEGIN
DBMS_SCHEDULER.CREATE_SCHEDULE (
schedule_name => 'my_weekend_5min_schedule',
start_date => SYSTIMESTAMP,
repeat_interval => 'FREQ=MINUTELY; INTERVAL=5; BYDAY=SAT,SUN',
end_date => SYSTIMESTAMP + INTERVAL '30' day,
comments => 'Every 5 minutes');
END;
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'my_user_count_job',
program_name => 'prog_insert_user_count',
schedule_name => 'my_weekend_5min_schedule');
END;
exec dbms_scheduler.enable('my_user_count_job’)
select * from user_count;
select job_name, status, run_duration, cpu_used
from USER_SCHEDULER_JOB_RUN_DETAILS
where job_name = ‘MY_USER_COUNT_JOB’;
Indeed your case should work but once(provided there already exists a row with id value equals to 1). Suppose you have an insert statement rather than an update, but doesn't repeat to populate the table with new incremented ID values.
For this, important point is to add repeat_interval argument such as below :
begin
dbms_scheduler.create_job(
job_name => 'test_job_A',
job_type => 'stored_procedure',
job_action => 'job_test',
start_date => SYSTIMESTAMP,
enabled => true,
repeat_interval => 'FREQ=MINUTELY;INTERVAL=5',
auto_drop => false,
comments => 'Inserts new records'
);
end;
/
which inserts new records for each five minutes.

Creating oracle JOB for my stored procedure

I'm trying to create an Oracle Job for c_insert_ship_confirm_start.
BEGIN
SYS.DBMS_SCHEDULER.CREATE_JOB (
job_name => '"CRCTFDC11XRQA"."SHIP_CONFIRM_JOB"',
job_type => 'STORED_PROCEDURE',
job_action => 'c_insert_ship_confirm_start(1000,FDC,1,0)',
number_of_arguments => 0,
start_date => TO_TIMESTAMP('09-MAR-16 02.41.43.451000000 PM', 'DD-MON-RR HH.MI.SS.FF AM'),
repeat_interval => 'FREQ=DAILY;BYDAY=FRI,MON,SAT,SUN,THU,TUE,WED;BYMINUTE=5',
end_date => NULL,
job_class => 'DEFAULT_JOB_CLASS',
enabled => false,
auto_drop => true,
comments => 'SHIP_CONFIRM_JOB IN EVERY 5 MINS',
credential_name => NULL,
destination_name => NULL);
END;
Stored procedure for reference::
create or replace procedure c_insert_ship_confirm_start
(
p_commit_frequency in number default 1000,
p_whse in varchar2,
p_debug_flag in number default 0,
p_rc out number
)
while creating JOB Oracle throwing error::
ORA-27452: %s is an invalid name for a database object
Arguments are not supported with stored_procedure job type. Reference: Oracle Docs
Use plsql_block
BEGIN
sys.dbms_scheduler.create_job(job_name => '"CRCTFDC11XRQA"."SHIP_CONFIRM_JOB"',
job_type => 'PLSQL_BLOCK',
job_action => 'begin c_insert_ship_confirm_start(1000,''FDC'',1,0); end;',
number_of_arguments => 0,
start_date => to_timestamp('09-MAR-16 02.41.43.451000000 PM',
'DD-MON-RR HH.MI.SS.FF AM'),
repeat_interval => 'FREQ=DAILY;BYDAY=FRI,MON,SAT,SUN,THU,TUE,WED;BYMINUTE=5',
end_date => NULL,
job_class => 'DEFAULT_JOB_CLASS',
enabled => FALSE,
auto_drop => TRUE,
comments => 'SHIP_CONFIRM_JOB IN EVERY 5 MINS',
credential_name => NULL,
destination_name => NULL);
END;
/

How Can We Delete A Table Row Automatically After a Specific Time in PL SQL

I have Tow table with Identical Columns Given Below:
Table-1 PAYROLLFILE:
Table-2 TEMP_PAYROLLFILE:
I have written a PL SQL Function, which inserts a duplicate row from Table PAYROLLFILE to TEMP_PAYROLLFILE and remove the original row from Table PAYROLLFILE.So in short, Table TEMP_PAYROLLFILE is keeping a backup for deleted data from Table PAYROLLFILE.
Here is the PL SQL Function Code:
FUNCTION Remove_transaction_by_id(employee_id NUMBER)
RETURN CLOB
AS
cnt INT;
BEGIN
INSERT INTO temp_payrollfile
SELECT *
FROM payrollfile
WHERE empid = employee_id;
DELETE FROM payrollfile
WHERE empid = employee_id;
SELECT Count(*)
INTO cnt
FROM payrollfile;
COMMIT;
RETURN '<result><status>success</status> <row>'
||cnt
|| '</row></result>';
EXCEPTION
WHEN OTHERS THEN
RETURN '<result><status>Error</status></result>';
END remove_transaction_by_id;
However, I want to do more than that, I want to Delete Backup rows Automatically from Table TEMP_PAYROLLFILE after a specific time period is over fort that specific row.Do i need triggers.I am new on that and never done this type of work before.If anyone know this kind of technique, then i would really appreciate your help.please let me know if further details required.Thanks
Updates:
I have write this job to cleanup old rows: will it work?
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'oe.REMOVE_TEMP_PAYROLLFILE_JOB',
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN DBMS_STATS.GATHER_TABLE_STATS('oe',
'TEMP_PAYROLLFILE');
delete from TEMP_PAYROLLFILE where RECORDDATE < sysdate-1;
END;',
start_date => '20-JAN-16 1.00.00AM US/Pacific',
repeat_interval => 'FREQ=DAILY',
end_date => '25-JAN-16 1.00.00AM US/Pacific',
enabled => TRUE,
comments => 'Gather table statistics');
END;
What you need here is a periodic cleanup job. Using DBMS_SCHEDULER you can configure a job that does this repeatedly:
delete from TEMP_PAYROLLFILE where recorddate < sysdate-60;
to delete records that are more than 60 days old.
These are some examples on how to create a scheduled job. As you see below, the job_action sections accepts a Pl/SQL script, in which you can place your cleanup logic.
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'oe.my_job1',
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN DBMS_STATS.GATHER_TABLE_STATS(''oe'',
''sales''); END;',
start_date => '15-JUL-08 1.00.00AM US/Pacific',
repeat_interval => 'FREQ=DAILY',
end_date => '15-SEP-08 1.00.00AM US/Pacific',
enabled => TRUE,
comments => 'Gather table statistics');
END;
/
Create a stored procedure to perform the deletion:
CREATE PROCEDURE remove_Temp_Transacts_by_ID(
in_employee_id IN NUMBER,
in_datetime IN TIMESTAMP
)
AS
BEGIN
DELETE FROM temp_payrollfile
WHERE empid = in_employee_id
AND datetime <= in_datetime;
END;
/
Then in your function include a call to schedule a job to run the procedure at a later time:
DBMS_SCHEDULER.CREATE_JOB(
JOB_NAME => 'Remove_TTbID__JOB',
JOB_TYPE => 'STORED_PROCEDURE',
JOB_ACTION => 'remove_Temp_Transacts_by_ID'
START_DATE => ( SYSTIMESTAMP + INTERVAL '2' HOURS ),
ENABLED => FALSE,
COMMENT => 'One time job to remove temporary payroll file entries'
);
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(
JOB_NAME => 'Remove_TTbID__JOB',
ARGUMENT_POSITION => 1,
ARGUMENT_VALUE => employee_id
);
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(
JOB_NAME => 'Remove_TTbID__JOB',
ARGUMENT_POSITION => 2,
ARGUMENT_VALUE => SYSTIMESTAMP
);
DBMS_SCHEDULER.ENABLE( 'Remove_TTbID__JOB' );

Using dbms_scheduler to run a program

I am trying to run a program using scheduler job.My code goes as follows:
--Program
BEGIN
dbms_scheduler.create_program (
program_name => 'firstprogram',
program_type => 'PLSQL_BLOCK',
program_action => 'BEGIN Execute immediate ''Create table xyz(id int, name varchar2(10))''; end;',
enabled => TRUE,
comments => 'First program');
END;
/
--Schedule
BEGIN
DBMS_SCHEDULER.create_schedule (
schedule_name => 'firstschedule',
start_date => SYSTIMESTAMP,
repeat_interval => 'freq=daily; byhour=14; byminute=25',
end_date => NULL,
comments => 'Repeats daily');
END;
/
--Job
BEGIN
dbms_scheduler.create_job (
job_name => 'firstjob',
program_name => 'firstprogram',
schedule_name => 'firstschedule',
enabled => TRUE,
comments => 'Use firstprogram and FirstSchedule');
END;
/
All these code blocks compile without showing any errors. But the table xyz is not created in the specified time. Can anyone explain me why? I am using Oracle.

Resources