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.
Related
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.
I have a couple of oracle procedures:
create or replace procedure receive_sms (p_to_date in date)
is
..
end;
and
create or replace procedure send_sms (p_date in date)
is
..
end;
and I want to create a chain based on these procedures and add steps to the chain and some rules:
BEGIN
DBMS_SCHEDULER.CREATE_CHAIN (
chain_name => 'mobile_archive_chain',
rule_set_name => NULL,
evaluation_interval => NULL,
comments => NULL);
END;
/
--- define three steps for this chain. Referenced programs must be enabled.
BEGIN
DBMS_SCHEDULER.DEFINE_CHAIN_STEP('mobile_archive_chain', 'send', 'inforpilla.send_sms');
DBMS_SCHEDULER.DEFINE_CHAIN_STEP('mobile_archive_chain', 'receive', 'inforpilla.receive_sms');
END;
/
--- define corresponding rules for the chain.
BEGIN
DBMS_SCHEDULER.DEFINE_CHAIN_RULE ('mobile_archive_chain', 'TRUE', 'START send');
DBMS_SCHEDULER.DEFINE_CHAIN_RULE ('mobile_archive_chain', 'send COMPLETED', 'Start receive');
DBMS_SCHEDULER.DEFINE_CHAIN_RULE ('mobile_archive_chain', 'receive COMPLETED', 'END');
END;
/
--- enable the chain
BEGIN
DBMS_SCHEDULER.ENABLE('mobile_archive_chain');
END;
/
--- create a chain job to start the chain daily at 1:00 p.m.
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'start_archive',
job_type => 'CHAIN',
job_action => 'mobile_archive_chain',
repeat_interval => 'freq=daily;byhour=15;byminute=3;bysecond=0',
enabled => TRUE);
END;
/
But checking the log table I see that the job failed with the ERROR code: 27475
SELECT * from USER_SCHEDULER_JOB_RUN_DETAILS ORDER BY LOG_DATE DESC
as suggested I remove the parameters form the procedure, but then I got these errors:
CHAIN_LOG_ID="201095"
CHAIN_LOG_ID="201095",STEP_NAME="RECEIVE", ORA-27475: "TEST.RECEIVE_SMS" must be a PROGRAM OR CHAIN
CHAIN_LOG_ID="201095",STEP_NAME="SEND", ORA-27475: "TEST.SEND_SMS" must be a PROGRAM OR CHAIN
There are couple of thing you need to make sure :
It is better to specify full job name in OWNER.JOBNAME. See who is owner of job
select * from dba_scheduler_jobs where lower(job_name)='start_archive';
If start_date and repeat_interval are left null, then the job is scheduled to run as soon as the job is enabled.
The job runs as the person that schedules the job, you should not be scheduling jobs as SYS if you want to use current user rights!
References :-
Oracle Community
Ask Tom
The problem could be in the chain, and chain steps names. Try to use upper case for all the job, chain, and chain steps or enclose the names with double quotes: " "
In oracle handles identifiers as case-insensitive and converts to upper case. Hence, oracle was unable to find your chain name. Same applies to chain steps, rules, etc
Also, the procedures "send" and "receive" expect parameters (p_to_date) and these parameters are not passed during chain step calls. This will cause a problem. There's no direct way for passing chain parameters. Have a look at this post: community.oracle.com/message/1459336#1459336
I think you have to use DBMS_SCHEDULER.CREATE_PROGRAM to create a program object and then pass the name of that object into DBMS_SCHEDULER.DEFINE_CHAIN_STEP. It looks like the third argument to DEFINE_CHAIN_STEP is a program name and you define that program name with a call to CREATE_PROGRAM.
Manual url:
http://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_sched.htm#ARPLS72235
I need to implement a heartbeat function written in PL/SQL, to ping a web service every 5 minutes. I know that PL/SQL is really not the correct language to be writing this in, but it has to be done this way.
DECLARE
stored_time TIMESTAMP
curr_time TIMESTAMP
BEGIN
stored_time := current_timestamp;
WHILE (curr_time - stored_time > 5)
pulse_heartbeat();
stored_time := current_timestamp;
END WHILE
The pseudo code above is really the only way i think it could be done. I know there is a timer package with oracle, but i'm not sure if i should use it or not. Any ideas?
It seems like you want to schedule the procedure execution every 5 minutes. I suggest use DBMS_SCHEDULER.
Database level
BEGIN
DBMS_SCHEDULER.create_job (
job_name => 'pulse_heartbeat',
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN pulse_heartbeat; END;',
start_date => SYSTIMESTAMP,
repeat_interval => 'freq=minutely; interval=5; bysecond=0;',
enabled => TRUE);
END;
/
Above uses calendaring syntax to repeat interval every 5 minutes. It creates a job at database level.
OS level
You could also schedule scripts to run at OS level. For example, in UNIX based platforms, you could create a shell script and schedule as cron job.
Hi I have a stored procedure in oracle that I would like to run periodically. Firstly I got my DBMS_SCHEDULER Job to compile (see below) and I can even see the job be created and drop it though I don't see the result of the stored procedure occur in the table it is supposed to effect and the stored procedure has been tested.
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'JOB_QUERY',
job_type => 'PLSQL_BLOCK', -- see oracle documentation on types --
job_action => 'BEGIN RUNREPORT(''NAME'', ''VERSION'', ''04-Jun-13'', ''11-Jun-13''); END;',
start_date => to_date('2013-08-19 16:35:00', 'YYYY-MM-DD HH24:MI:SS' ),
repeat_interval => 'FREQ=MINUTELY;BYMINUTE=10', -- every 10 minutes.
end_date => NULL,
enabled => TRUE,
comments => 'Daily Jira Query Update');
END;
I was attempting to simply make it run every ten minutes though I see no changes. Also I wanted to be able to pass SYSDATE or the current date to the procedure in the dbms_scheduler job but I cant get it to work with the apostrophes.
Thanks
You have to COMMIT your DML statements. There is no COMMIT in PL/SQL block and I guess in procedure RUNREPORT either.
You don't need an apostrophe around sysdate, it's not a string literal.
job_action => 'BEGIN RUNREPORT(''NAME'', ''VERSION'', sysdate, ''11-Jun-13''); COMMIT; END;',
BYMINUTE does not mean what you would expect. From documentation:
"This specifies the minute on which the job is to run. Valid values are 0 to 59. As an example, 45 means 45 minutes past the chosen hour". What you need is
repeat_interval => 'FREQ=MINUTELY;INTERVAL=10'
You can check next run date and more by querying user_scheduler_jobs.
If you are calling the stored procedure from DMBS Scheduled job you can try below.
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
JOB_NAME => 'SCHEMA.MY_DBMS_SCHEDULED_JOB',
JOB_TYPE => 'STORED_PROCEDURE',
JOB_ACTION => 'SCHEMA.STORED_PROCEDURE_TO_BE_CALLED',
START_DATE => '01-AUG-13 12.00.00 AM',
REPEAT_INTERVAL => 'FREQ=DAILY;BYHOUR=0;BYMINUTE=10',
AUTO_DROP => FALSE,
ENABLED => TRUE,
NUMBER_OF_ARGUMENTS => 0,
COMMENTS => 'Scheduled job to perform updates.');
END;
/
To see if your scheduler log you can use below query.
SELECT * FROM all_SCHEDULER_JOB_LOG
where job_name='MY_DBMS_SCHEDULED_JOB'
order by log_id desc;
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.