So what we trying to do is create a procedure that execute a batch file.
We been messing around with job instruction, but it seems like it doesn't work properly.
CREATE OR REPLACE PROCEDURE launch_bat AS
BEGIN
DBMS_SCHEDULER.create_job ('Export_Case_Job',
job_action => 'C:\WINDOWS\SYSTEM32\CMD.EXE',
number_of_arguments => 3,
job_type => 'executable',
enabled => FALSE);
DBMS_SCHEDULER.set_job_argument_value ('Export_Case_Job', 1, '/q');
DBMS_SCHEDULER.set_job_argument_value ('Export_Case_Job', 2, '/c');
DBMS_SCHEDULER.set_job_argument_value ('Export_Case_Job', 3, 'C:\scripts\helloFolder.bat');
DBMS_SCHEDULER.enable ('Export_Case_Job');
END;
/
call launch_bat;
It says that it compiled but we don't see any result in our folder. We also tried to give a file name in call.
We have Oracle 10.2 so we can't use exec xp_cmdshell.
Why procedure ? When we get new income data, we will execute a trigger with procedure that will go for a batch file, this batch file will create a certain information inside our folders as a test purporse.
The main focus is that oracle sql execute a batch file.
Batch content
ECHO OFF
mkdir C:\scripts\folder
Thanks in advance !
When I compare your example with the one from the docs https://docs.oracle.com/cd/E11882_01/server.112/e25494/scheduse.htm#CHDJHBAH:
BEGIN
DBMS_SCHEDULER.CREATE_JOB(
job_name => 'MKDIR_JOB',
job_type => 'EXECUTABLE',
number_of_arguments => 3,
job_action => '\windows\system32\cmd.exe',
auto_drop => FALSE,
credential_name => 'TESTCRED');
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE('mkdir_job',1,'/c');
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE('mkdir_job',2,'mkdir');
DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE('mkdir_job',3,'\temp\extjob_test_dir');
DBMS_SCHEDULER.ENABLE('MKDIR_JOB');
END;
/
EXECUTABLE vs. executable
\windows\system32\cmd.exe vs C:\WINDOWS\SYSTEM32\CMD.EXE
So I would expect that you have to write job_type in upper case. Probably job_action lower case, but I'm not sure there.
If the error is somewhere else you have to check:
*_SCHEDULER_JOB_LOG
*_SCHEDULER_JOB_RUN_DETAILS
Where I could find sufficiant information to migrate the example from the docs to linux with mkdir.
Related
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 have created below code, create_job is working fine but dbms_scheduler.enable is not running jobs automatically, however If I manually run created job i.e. begin REQUEST_PKG.CREATE_REQUEST('1234'); end; it runs successfully. Can someone please help me out here, to me it seems some compatibility/parameter passing issue in dbms_scheduler.enable.
DBMS_SCHEDULER.create_job
(job_name => job_name,
job_type => 'PLSQL_BLOCK',
job_action => 'begin REQUEST_PKG.CREATE_REQUEST('||seq_no|| '); end; ',
enabled => FALSE,
auto_drop => FALSE,
comments => seq_no
);
DBMS_SCHEDULER.ENABLE(job_name);
I am using oracle version 11.2.0.4.0.
Check your database initialization parameters. Specifically JOB_QUEUE_PROCESSES.
Documentation says :
If the value of JOB_QUEUE_PROCESSES is set to 0, then DBMS_JOB jobs and Oracle Scheduler jobs will not run on the instance.
I have created a Job using this.
BEGIN
dbms_scheduler.create_job (
job_name => 'test_JOB',
job_type => 'PLSQL_BLOCK',
JOB_ACTION => 'UP_TRYNR;',
start_date =>sysdate,
enabled => true,
repeat_interval => 'FREQ=DAILY;INTERVAL=1'
);
END;
If I create the job without specifying repeat_interval what will happen? i.e.
BEGIN
dbms_scheduler.create_job (
job_name => 'test_JOB',
job_type => 'PLSQL_BLOCK',
JOB_ACTION => 'UP_TRYNR;',
start_date =>sysdate,
enabled => true,
);
END;
Any suggestion will be helpful. Thanks.
The DBMS_SCHEDULER package includes functionality that can be used to set up and manage the timetabling and execution of tasks that need to be run according to a – repeating or non-repeating – schedule.
DBMS_SCHEDULER breaks the process of scheduling a task into 3 parts:
Create a schedule
Identify a ‘program’ – by which they mean the procedure you wish to
run
Create a ‘job’ – by which they mean chain a program to a schedule.
As name suggests Repeat_interval,describes the frequency when the programs needs to be executed. This is a bit like the cron syntax in UNix.
If you create it without any Repeat_interval,it would execute only once at the specified startdate and then remain dormant.
I'm currently using:
BEGIN
PACKAGE1.PROCEDURE1('PARAM_1','PARAM_A','PARAM_B');
END;
I need to run the same procedure multiple times (Oracle), but this time changing only the first parameter, for example:
PACKAGE1.PROCEDURE1('PARAM_2','PARAM_A','PARAM_B');
PACKAGE1.PROCEDURE1('PARAM_3','PARAM_A','PARAM_B');
How can i accomplish this? Thank you in advance.
In anonym plsql block write a loop with number of iteration depends on how many parameters You want to call procedure with. At the top of loop put logic that will be setting a paramter an then call a procedure with it. But remember that there is no option in plsql to read data from console or user during a program run.
// I think that You can ask about passing an other variable in loop each time, I am not sure is it can be done in plsql You can try use
execute_immidiate
command with string conncatenate as a parameter name.
You Package Procedure must be with IN OUT parameter and i assume the first parameter is IN so the master should take care of the thing of supplying the values to this.
Procedure is working as expected now the external stream of incoming this have to take which is coming from outer source or some other passing mechanism.
Just align those to this package procedure and you may call this procedure as many time as you want according to IN this takes.
You could try to submit it as job if you want to run the same procedure simultaneously.
BEGIN
begin
dbms_scheduler.create_job
(
job_name => 'One_Time_Job_1',
job_type => 'PLSQL_BLOCK',
job_action => 'begin PACKAGE1.PROCEDURE1('PARAM_2','PARAM_A','PARAM_B'); end;',
start_date => sysdate,
enabled => TRUE,
auto_drop => TRUE,
comments => 'one-time job');
end;
begin
dbms_scheduler.create_job
(
job_name => 'One_Time_Job_2',
job_type => 'PLSQL_BLOCK',
job_action => 'begin PACKAGE1.PROCEDURE1('PARAM_3','PARAM_A','PARAM_B'); end;',
start_date => sysdate,
enabled => TRUE,
auto_drop => TRUE,
comments => 'one-time job');
end;
END;
look at DBMS_SCHEDULER for further details.
If this is for an ongoing production process with a fixed number of parallel procedures, I would consider using a Scheduler Chain.
This would execute all the procedures at the same time, and give you extra features, such as:
the ability to run other procedures when one or all of them has completed
control over which procedures run afterwards, depending on the success or failure of the procedures.
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.