I'm trying to create a job, which creates a folder, with DBMS_SCHEDULER. I try to do it with the procedure below:
PROCEDURE MAKE_FOLDER (sDir IN VARCHAR2, sName IN VARCHAR2, sCred IN VARCHAR2) AS
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
JOB_NAME => sName, --- job name
JOB_ACTION => 'C:\Windows\System32\cmd.exe', --- executable file with path
JOB_TYPE => 'EXECUTABLE', ----- job type
NUMBER_OF_ARGUMENTS => 2, -- parameters in numbers
ENABLED => false,
AUTO_DROP => true,
CREDENTIAL_NAME => sCred, -- give credentials name
COMMENTS => 'folder or os directory creation');
--DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(sName,1,'/c');
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(sName,1,'mkdir');
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(sName,2,sDir);
DBMS_SCHEDULER.ENABLE(sName);
DBMS_SCHEDULER.RUN_JOB(sName);
END ;
However when I execute this procedure I'm getting an ORA-27369 error:
ORA-27369: job of type EXECUTABLE failed with exit code: 9 Couldn't for process.
What is wrong?
Related
I am trying to create a simple SQL job in Oracle using SQL Developer. This job will run daily and will execute one stored procedure.
The script is:
DBMS_SCHEDULER.CREATE_JOB (
job_name => '"schema1"."jobName"',
job_type => 'STORED_PROCEDURE',
job_action => 'schema1.import1.sp_import',
number_of_arguments => 0,
start_date => TO_TIMESTAMP_TZ('2021-01-12 14:31:21.000000000 AMERICA/NEW_YORK','YYYY-MM-DD HH24:MI:SS.FF TZR'),
repeat_interval => 'FREQ=DAILY;BYTIME=144500;BYDAY=MON,TUE,WED,THU,FRI',
end_date => NULL,
enabled => FALSE,
auto_drop => FALSE,
comments => 'This job will populate date in new table.');
Upon execution of this I am getting below error:
Error starting at line : 2 in command -
DBMS_SCHEDULER.CREATE_JOB (
Error report -
Unknown Command
Any idea?
Cause of that error is, I believe, the fact that you didn't enclose DBMS_SCHEDULER.CREATE_JOB into a BEGIN-END block:
begin
dbms_scheduler.create_job(...);
end;
/
Also, repeat_interval looks wrong (at least, in my 11g). There's no BYTIME - use BYHOUR and BYMINUTE combination instead. Something like this (note that I don't have your procedure):
SQL> BEGIN
2 DBMS_SCHEDULER.CREATE_JOB (
3 job_name => 'test',
4 job_type => 'STORED_PROCEDURE',
5 job_action => 'p_test',
6 number_of_arguments => 0,
7 start_date => TO_TIMESTAMP_TZ('2021-01-12 14:31:21.000000000 AMERICA/NEW_YORK','YYYY-MM-DD HH24:MI:SS.FF TZR'),
8 repeat_interval => 'FREQ=DAILY;BYDAY=MON,TUE,WED,THU,FRI;BYHOUR=14;BYMINUTE=45',
9 end_date => NULL,
10 enabled => FALSE,
11 auto_drop => FALSE,
12 comments => 'This job will populate date in new table.');
13 END;
14 /
PL/SQL procedure successfully completed.
SQL>
I am trying to run stored procedures in parallel - Oracle PL/SQL using dbms_scheduler but I am getting an error like an unknown job, I have also tried dbms_job, here I am getting an error- identifier dbms_jobs must be declared. Could someone please help me out?
Below are two approaches I have tried:
CREATE PACKAGE BODY pkg IS
CREATE PROCEDURE do_parallel_execution
IS
BEGIN
DBMS_SCHEDULER.RUN_JOB('pkg1.proc1', false);
DBMS_SCHEDULER.RUN_JOB('pkg1.proc2', false);
DBMS_SCHEDULER.RUN_JOB('pkg1.proc3', false);
END;
CREATE PACKAGE BODY pkg IS
CREATE PROCEDURE run_in_parallel
IS
l_jobno pls_integer;
BEGIN
dbms_job.submit(l_jobno, 'pkg1.proc1; end;' );
dbms_job.submit(l_jobno, 'pkg1.proc2; end;' );
-- dbms_job.submit(l_jobno, 'pkg1.proc3; end;' );
END;
where pkg1 has all 3 procedures defined in it.
Thank you!
To execute otherwise unrelated procedures in parallel, use a Scheduler Job Chain:
Create procedures:
create or replace package test as
procedure test1;
procedure test2;
procedure test3;
end test;
/
create or replace package body test as
procedure test1 is
begin
sys.dbms_session.sleep(5);
end test1;
procedure test2 is
begin
sys.dbms_session.sleep(5);
end test2;
procedure test3 is
begin
sys.dbms_session.sleep(5);
end test3;
end test;
/
Create Scheduler Programs for each procedure:
BEGIN
DBMS_SCHEDULER.create_program(
program_name => 'TEST1_PROGRAM',
program_action => 'TEST.TEST1',
program_type => 'STORED_PROCEDURE',
number_of_arguments => 0,
comments => NULL,
enabled => FALSE);
DBMS_SCHEDULER.ENABLE(name=>'TEST1_PROGRAM');
DBMS_SCHEDULER.create_program(
program_name => 'TEST2_PROGRAM',
program_action => 'TEST.TEST2',
program_type => 'STORED_PROCEDURE',
number_of_arguments => 0,
comments => NULL,
enabled => FALSE);
DBMS_SCHEDULER.ENABLE(name=>'TEST2_PROGRAM');
DBMS_SCHEDULER.create_program(
program_name => 'TEST3_PROGRAM',
program_action => 'TEST.TEST3',
program_type => 'STORED_PROCEDURE',
number_of_arguments => 0,
comments => NULL,
enabled => FALSE);
DBMS_SCHEDULER.ENABLE(name=>'TEST3_PROGRAM');
END;
/
Create the Scheduler Chain:
BEGIN
-- one step for each program
SYS.DBMS_SCHEDULER.DEFINE_CHAIN_STEP (
chain_name => 'TEST_CHAIN'
,step_name => 'CHAIN_STEP1'
,program_name => 'TEST1_PROGRAM');
SYS.DBMS_SCHEDULER.DEFINE_CHAIN_STEP (
chain_name => 'TEST_CHAIN'
,step_name => 'CHAIN_STEP2'
,program_name => 'TEST2_PROGRAM');
SYS.DBMS_SCHEDULER.DEFINE_CHAIN_STEP (
chain_name => 'TEST_CHAIN'
,step_name => 'CHAIN_STEP3'
,program_name => 'TEST3_PROGRAM');
-- one rule with condition "true" to start each step immediately
SYS.DBMS_SCHEDULER.DEFINE_CHAIN_RULE (
CHAIN_NAME => 'TEST_CHAIN',
rule_name => 'TEST_RULE1',
condition => 'TRUE',
action => 'START "CHAIN_STEP1"');
SYS.DBMS_SCHEDULER.DEFINE_CHAIN_RULE (
CHAIN_NAME => 'TEST_CHAIN',
rule_name => 'TEST_RULE2',
condition => 'TRUE',
action => 'START "CHAIN_STEP2"');
SYS.DBMS_SCHEDULER.DEFINE_CHAIN_RULE (
CHAIN_NAME => 'TEST_CHAIN',
rule_name => 'TEST_RULE3',
condition => 'TRUE',
action => 'START "CHAIN_STEP3"');
-- one rule to close out the chain after all steps are completed
SYS.DBMS_SCHEDULER.DEFINE_CHAIN_RULE (
chain_name => 'TEST_CHAIN',
rule_name => 'TEST_RULE4',
condition => 'CHAIN_STEP1 Completed AND CHAIN_STEP2 Completed AND CHAIN_STEP3 Completed',
action => 'END 0');
END;
/
The chain flow now looks like this (as depicted by SQL Developer):
Now create a Scheduler Job to run the chain:
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'TEST_JOB',
job_type => 'CHAIN',
job_action => 'TEST_CHAIN',
number_of_arguments => 0,
start_date => NULL,
repeat_interval => NULL,
end_date => NULL,
enabled => FALSE,
auto_drop => FALSE,
comments => '');
DBMS_SCHEDULER.SET_ATTRIBUTE(
name => 'TEST_JOB',
attribute => 'logging_level', value => DBMS_SCHEDULER.LOGGING_RUNS);
END;
/
And run the job:
BEGIN
DBMS_SCHEDULER.RUN_JOB(job_name => 'TEST_JOB', USE_CURRENT_SESSION => FALSE);
END;
/
Now look at the job run details for the job:
"LOG_ID" "LOG_DATE" "JOB_NAME" "JOB_SUBNAME" "STATUS" "ERROR#" "ACTUAL_START_DATE" "RUN_DURATION"
"1548" "14-JUN-20 12.15.46.744612000 AM -04:00" "TEST_JOB" "CHAIN_STEP3" "SUCCEEDED" "0" "14-JUN-20 12.15.41.708043000 AM AMERICA/NEW_YORK" "+00 00:00:05.000000"
"1544" "14-JUN-20 12.15.46.746544000 AM -04:00" "TEST_JOB" "CHAIN_STEP2" "SUCCEEDED" "0" "14-JUN-20 12.15.41.690404000 AM AMERICA/NEW_YORK" "+00 00:00:05.000000"
"1546" "14-JUN-20 12.15.46.748830000 AM -04:00" "TEST_JOB" "CHAIN_STEP1" "SUCCEEDED" "0" "14-JUN-20 12.15.41.690891000 AM AMERICA/NEW_YORK" "+00 00:00:05.000000"
"1550" "14-JUN-20 12.15.46.968592000 AM -04:00" "TEST_JOB" "" "SUCCEEDED" "0" "14-JUN-20 12.15.41.574115000 AM AMERICA/NEW_YORK" "+00 00:00:05.000000"
Note that:
The job starts at "12.15.41.574115000" (ACTUAL_START_DATE, Line 1550).
Each job step starts within a fraction of a second of the overall job start (as recorded in ACTUAL_START_DATE for each step in lines 1544, 1546, and 1548), and completes in the expected 5 seconds.
The overall job completes at "14-JUN-20 12.15.46.968592000" (LOG_DATE, Line 1550) with a total duration of 5 seconds to complete all three steps.
Note that rule processing may add a tiny bit of overhead to the total execution time for the chain.
The parallel processing can be achieved using the schedule job chain.
create schedule programs with the procedure function you want to run,
create a scheduler chain and define steps and rules,
create a job/scheduler job to call the scheduler chain
I have a Linux Oracle Server. The database is generating CSV files with a custom stored procedure, now at the end of this procedure. I want to execute a bash/shell script in linux to push this files to Amazon S3 Bucket.
I am getting errors trying to schedule the process in oracle:
EXTERNAL_LOG_ID="job_2369137_852690",
ORA-27369: job of type EXECUTABLE failed with exit code: Argument list too long
Using DBM_SCHEDULER to create a JOB type Sript, External
#!/bin/bash
echo hello world
DBMS_SCHEDULER.CREATE_JOB (
job_name => '"ODSMGR"."TEST_JOB"',
job_type => 'EXTERNAL_SCRIPT',
job_action => '#!/bin/bash
echo hello world',
number_of_arguments => 0,
start_date => NULL,
repeat_interval => NULL,
end_date => NULL,
enabled => FALSE,
auto_drop => FALSE,
comments => '');
The DBMS_SCHEDULER.CREATE_JOB you are using has incorrect arguments. You should preferably follow these standard steps for running a program.
First create a program with appropriate name and define what to run. In the below example I'm running a bash command directly, You may put them into a separate shell script with relevant permissions and add its name under program_action
BEGIN
DBMS_SCHEDULER.CREATE_PROGRAM (
program_name=> 'COPY_PROGRAM',
program_type=> 'EXECUTABLE',
program_action => '/bin/bash -c "echo hello world"',
enabled=> TRUE,
comments=> 'Push files to Amazon S3 Bucket.'
);
END;
/
Then, create the job using that program.
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'TEST_JOB',
program_name => 'COPY_PROGRAM',
start_date => NULL,
repeat_interval => NULL,
end_date => NULL,
enabled => FALSE,
auto_drop => FALSE,
comments => '');
END;
/
Refer this link for more details.
I am trying to create oracle scheduler job (send mail) by pl/sql process (job is created on button click). It create job successfully but job always finish with error:
"ORA-20001: Security Group ID (your workspace identity) is invalid. ORA-06512: at "APEX_050100.WWV_FLOW_SECURITY", line 2939 ORA-06512: at
"APEX_050100.HTMLDB_UTIL", line 3014 ORA-06512: at line 7 ORA-06512:
at line 7.
I also have tried to set security_group_id directly (apex_util.set_security_group_id(p_security_group_id => my_worspace_id or
wwv_flow_api.set_security_group_id(p_security_group_id=>my_worspace_id) but it always finish with the same error as my sample code. When i try to create job manually in sql developer it works. But when job is created by pl/sql process it finish with the mentioned error. Job is created successfully in both cases (pl/sql process or manually) with the same parameters so i do not understand why in case when job is created by pl/sql process it finish with error.
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => '"INVERTORY"."TEST"',
job_type => 'PLSQL_BLOCK',
job_action => 'begin
for c1 in (
select workspace_id
from apex_applications
where application_id = 104 )
loop
apex_util.set_security_group_id(p_security_group_id =>
c1.workspace_id);
end loop;
HTMLDB_MAIL.SEND(
p_to => ''****.****#****.com'',
p_from => ''noreply#****.com'',
p_subj => ''test mail'',
p_body => ''komu'');
end;',
number_of_arguments => 0,
start_date => TO_TIMESTAMP_TZ('2017-08-28 10:29:57.000000000 EUROPE/PRAGUE','YYYY-MM-DD HH24:MI:SS.FF TZR'),
repeat_interval => NULL,
end_date => NULL,
enabled => TRUE,
auto_drop => FALSE,
comments => '');
DBMS_SCHEDULER.SET_ATTRIBUTE(
name => '"INVERTORY"."TEST"',
attribute => 'logging_level', value => DBMS_SCHEDULER.LOGGING_OFF);
DBMS_SCHEDULER.enable(
name => '"INVERTORY"."TEST"');
END;
Try changing this :
for c1 in (
select workspace_id
from apex_applications
where application_id = 104 )
loop
apex_util.set_security_group_id(p_security_group_id =>
c1.workspace_id);
end loop;
To this :
SELECT MAX(workspace_id)
INTO v_workspace FROM apex_applications
WHERE application_id = 104;
--set workspace - declare v_workspace above as type number
wwv_flow_api.set_security_group_id(v_workspace)
In any event, it would be better to put your logic in a package in the database and create a job with job_type => 'STORED_PROCEDURE' and call on your procedure from there.
I am a little new to programming, so any help is appreciated.
Find below the code of my stored proc to delete a table and also create a DBA job which will run on a hourly basis.
CREATE OR REPLACE procedure DELETE_My_TABLE(myschema varchar2) as
BEGIN
BEGIN
execute immediate 'delete from '||myschema||'.mytable where clause;';
END;
BEGIN
DBMS_SCHEDULER.create_program (
program_name => 'DELETE_My_TABLE',
program_type => 'STORED_PROCEDURE',
program_action => 'execute DELETE_My_TABLE(myschema)',
number_of_arguments => 1,
enabled => FALSE,
comments => 'Program to delete table using a stored procedure.');
DBMS_SCHEDULER.define_program_argument (
program_name => 'DELETE_My_TABLE',
argument_name => 'myschema',
argument_position => 1,
argument_type => 'VARCHAR2',
default_value => 'myschema');
DBMS_SCHEDULER.enable (name => 'DELETE_My_TABLE');
END;
BEGIN
DBMS_SCHEDULER.create_schedule (
schedule_name => 'DELETE_My_TABLE',
start_date => SYSTIMESTAMP,
repeat_interval => 'freq=hourly; byminute=0',
end_date => NULL,
comments => 'Hourly Job to purge SEARCH_TEMP_TABLE');
END;
END;
/
Issues:
ERROR at line 1:
ORA-00920: invalid relational operator
ORA-06512: at "MYSCHEMA.DELETE_My_TABLE", line 4
ORA-06512: at line 1
Will the logic (and syntax) work?
One issue I can see is that you need to take the semi-colon out of the EXECUTE IMMEDIATE string:
execute immediate 'delete from '||myschema||'.mytable where clause';
^^
Removed from here
thought I suspect this won't solve your immediate problem, which looks like it's your BEGIN ...END blocks.
For the Oracle Scheduler you normally create a program, once. Next you create a job that has the program as action. You can give that job a schedule like you specified in your code but you have to choose. Either you create a schedule and have the job use it, or you give the job it's own repeat interval.
I happen to know about a book ( Mastering Oracle Scheduler ) that I wrote that could be very helpful.