Bhaskar, January 06, 2003 - 12:59 am UTC
Hi Tom,
Well i executed that thing and it worked fine.
Thanks for the reply !!
Bhaskar
How about no wrapping at all?
Doug, April 25, 2003 - 9:44 pm UTC
Tom, are there any risks with just passing in a simple statement?
SQL> begin
2 dbms_job.isubmit(40,'delete from ORDER_SUB where end_date <= sysdate;',
3 trunc(sysdate),'TRUNC(SYSDATE+1)');
4 end;
5 /
It will commit?
It will break appropriately?
April 26, 2003 - 8:22 am UTC
it will work fine.
automate execute procedure
A reader, September 15, 2004 - 3:56 pm UTC
Hi Tom,
I have a procedure sp_testproc which takes 2 input parameters. In order to execute the procedure I will do the foll
exec sp_testproc(input1, input2);
Now I am running this manually in my SQL* Plus sessions. Is it possible for me to just automate this exec proc?
Thanks.
September 15, 2004 - 4:12 pm UTC
define "automate this exec proc"
what do you want to do?
Is it possible?
A reader, September 16, 2004 - 4:46 pm UTC
Hi Tom,
I am calling stored procedures (bundled in a package) with different arguments (where procedure is same but argument is different) through a scheduling tool.I want to execute these procedures in parallel. Can I do this?
Call main procedure..
which in turn calls p(1) execute, p(2) execute....
If all successful then main is succussful. The idea is to execute p(1)... in parallel, but controlling through p(main)
Thanks
September 16, 2004 - 7:45 pm UTC
what is the scheduling tool
isn't that what a scheduling tool does??
But I am facing some problem....
A reader, September 17, 2004 - 5:25 am UTC
Hi Tom,
You are right that scheduling tool does all this. But when I was monitoring the job in unix, I found that processes are running but not doing much, and CPUs are idle 50% of the time. At that time, I thought to run straight from oracle procedure eliminating any other software in between. But on manually running outside, I found the same problem. What I am doing:
p(a) reads from temp table for a state and product loads data in target
p(b) does same thing with different state and other product
.......
Could it be bottleneck becuase I am inserting in the same target???
I thought that I can issue multiple inserts into the same target in Oracle efficiently or I am missing something?
I also tested that when I run procedures serially or in parralel, the loading time is almost same. Will partitioning in target table with state/product will help??? Is it locking issue etc???
Thanks
September 17, 2004 - 9:17 am UTC
there is insufficient data here to diagnose anything (and don't add more).
Do you have any of my books or Cary Millsaps book?
Books....
A reader, September 17, 2004 - 9:11 pm UTC
Thanks Tom.
Can you mention the specific Chapter(s) of your or Cary's books in this context?
Regards
September 17, 2004 - 9:12 pm UTC
chapter 10 expert one on one Oracle
all about using 10046 trace to tune an application.
Cary's book -- pages 1 .. infinity
Bit of challenge...
A reader, September 18, 2004 - 1:59 am UTC
Hi Tom,
I had a look at chapter 10 of your book, and Cary's book. I don't think it will be worth spending time on Cary's book to tune for the sake of saving few hours, as the Job is once a month, and takes 10 hours in all.
btw: For smaller set of products, the result is very quick. Does this give some indication to look for low hanging fruit?
Thanks
September 18, 2004 - 10:33 am UTC
spending time on Cary's book will help you for the rest of your life.
confusion here on my part, it is not like knowledge learned for task "A" is forgotten never to be applied again?
but hey -- if you say "saving a few hours from 10 isn't worth it", then why are we having this discussion in the first place? apparently, while 10 hours is a long time, it is short enough?
if you multiply the time taken for "small" into "large" (eg: small is 100 products and runs in 5 seconds. large is 100,000. is 5,000 seconds still quick to you?)
Agreed but...
A reader, September 18, 2004 - 6:58 pm UTC
Hi Tom,
Thanks a lot. I fully agree with you that knowledge acquired will never be wasted (and also I admire your help and knowledge too).
The problem here is to deliver something also, which I think I won't be able to deliver if I start reading Cary's book (1...infinity). I will defintely read it (thanks for showing me the light), but unfortunately I have to weigh between either to delay the deliverables by making it in the best way, or deliver something as per target, and then re-visit. The reason I put here because I thought I found the problem and can easily be fixed with your magic help. The findings were:
When I run procedures in parallel
-- Parallel process A
exec P(for state S1, product p1)
product p1 (about couple of thousand rows) -- few minutes
exec P(for state S1, product p2)
product p2 (couple of million rows) -- about 2.5 hours
-- Parallel process B
exec P(for state S2, product p1)
product p1 (about couple of thousand rows) -- few minutes
exec P(for state S2, product p2)
product p2 (couple of million rows; more than s1,p2) -- about 4 hours
-- Parallel process C
exec P(for state S3, product p1)
product p1 (about couple of thousand rows) -- few minutes
exec P(for state S3, product p2)
product p2 (couple of miilion rows; more than s1, p2 and < s2,p2) -- about 3.5 hours
________________
Then, I tried to exec in parallel
p(s1,p2), p(s2,p2) and p(s3,p2), I thought if I am able to utilise parallel processing, it should not take T(s1,p2)+T(s2,p2)+T(s3,p3), but the whole process took around same time - around 10 hours!, and When I was monitoring through vmstat, I found that most of the time running processes were 1 (no blocked, no paging), cpu's 50% idle etc..
The oracle version is 9.2 on AIX 5.2L
Thanks
September 19, 2004 - 10:18 am UTC
the only thing I can suggest is a 10046 level 12 trace. what are your applications *waiting* on. Doesn't appear to be CPU, so now you need to find out what.
my chapter 10 is a brief introduction to that.
Carys book is the literal deep dive.
Thanks a lot!
A reader, September 19, 2004 - 4:44 pm UTC
Hi Tom,
Thanks for your help.
I will try based upon chapter 10.
Regards
Scheduling of Job
Jignesh, February 18, 2005 - 5:46 am UTC
Hi Tom,
There is a task which should begin after commit & based on the keys that are updated.
My plan is to implement this using :
1. Create on update trigger
2. Create job in ON UPDATE TRIGGER using dynamic SQL and schedule it to run after say 15 seconds.
3. Delete that job( where ? ? still not clear)
Is there any better way of doing this? ?
February 18, 2005 - 8:57 am UTC
where did dynamic sql come into play?
it would look like this:
create table job_parameters( jobid number primary key,
<other inputs needed by your job> );
create or replace trigger
after update on t for each row
declare
l_job number;
begin
dbms_job.submit( l_job, 'my_background_procedure(JOB);' );
insert into job_parameters values ( l_job, :new....... );
end;
/
and your background procedure would resemble:
create or replace procedure my_background_procedure(p_jobid in number)
is
l_rec job_parameters%rowtype;
begin
select * into l_rec from job_parameters where jobid = p_jobid;
....process....
delete from job_parameters where jobid = p_jobid;
commit;
end;
/
that will schedule a one time job (it removes itself all by itself after it successfully completes).
that job (my_background_procedure) will get its unique JOB id as input, we'll have used to that store the parameters for this job occurrence in a table -- that makes this job very "bind variable friendy" (rather than gluing the values into the plsql block itself, generating unique SQL for the job queue process to execute).
We clean up the row in the parameter table and are done.
Please ignore my last review
Jignesh, February 18, 2005 - 7:33 am UTC
Hi Tom,
I have implemented the same thing using autonomous transaction in triggers and things are working now.
Thanks for your time
February 18, 2005 - 9:14 am UTC
stop -- stop -- STOP
erase that trigger... totally back up the bus.
autonomous transactions are evil, you *might* be able to use them for auditing -- MAYBE. beyond that, evil.
show me what you are doing and I'll show you how very very very bad it is.
use the above, it is transactional (if you rollback the update, the job goes away). it is *easy*. it is correct. it is SAFE
Here is my code....
Jignesh, February 18, 2005 - 10:33 am UTC
I refered to metalink Note:208599.1 and followed the same :
Trigger :
create or replace trigger trig_rw_server_queue after update on rw_server_queue for each row
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
v_seq_id number;
BEGIN
if :new.status_code = 3 then
v_seq_id := :new.rep_run_id;
p_run_job (v_seq_id);
end if;
END;
/
Procedure :
Create or replace procedure
p_run_job(p_report_id Number) as
Jobid Number := 0;
ProcNm Varchar2(200) := 'pkg_report.UPDATE_STATUS('||p_report_id||')';
Begin
ProcNm := 'Begin '||ProcNm||'; End;';
Dbms_job.Submit(Jobid,ProcNm,Sysdate+1/1440,null);
Commit;
End;
/
And the package.procedure
PROCEDURE UPDATE_STATUS (P_REP_KEY NUMBER) IS
v_job_Id SRW_ONE.Job_Ident;
V_rep_Status SRW_ONE.Status_Record;
P_JOB_ID NUMBER;
P_MESSAGE VARCHAR2(2000);
BEGIN
COMMIT;
BEGIN
SELECT job_id
INTO P_JOB_ID
FROM RW_SERVER_QUEUE
WHERE REP_RUN_ID = P_REP_KEY;
EXCEPTION
WHEN NO_DATA_FOUND THEN
P_MESSAGE := P_REP_KEY||SQLERRM;
RAISE_APPLICATION_ERROR (-20002, sqlerrm);
insert into rw_server_queue ( REP_RUN_ID, JOB_ID, status_text )
values ( P_REP_KEY ,v_job_id.jobid, SUBSTR(P_MESSAGE,1,100));
commit;
END;
v_job_Id.JobID := P_JOB_ID;
SRW_ONE.DEBUGGING := TRUE;
-- myPlist := SRW_PARAMLIST(SRW_PARAMETER('',''));
v_job_Id.ServerName := F_MIC_LOOKUP('SERV_PARA','SERVER');
v_job_Id.GatewayURL := F_MIC_LOOKUP('SERV_PARA','GATEWAY');
V_rep_Status := SRW_ONE.Report_Status(v_job_Id);
UPDATE RW_SERVER_QUEUE
SET status_code = nvl(V_rep_Status.StatusCode,88),
status_text = nvl(V_rep_Status.StatusText,'null')
WHERE rep_run_id = p_rep_key;
dbms_output.put_line(V_rep_Status.JobIdent.JobID);
dbms_output.put_line(V_rep_Status.JobIdent.ServerName);
dbms_output.put_line(V_rep_Status.JobType);
dbms_output.put_line(V_rep_Status.OutputType);
dbms_output.put_line(V_rep_Status.OutputName);
dbms_output.put_line(V_rep_Status.QueuedAt);
dbms_output.put_line(V_rep_Status.StartedAt);
dbms_output.put_line(V_rep_Status.FinishedAt);
dbms_output.put_line(V_rep_Status.ParentJob);
exception when others then
RAISE_APPLICATION_ERROR (-20001, sqlerrm);
END;
The whole story behind this stuff is:
We are calling report using event based report.. from database which runs in background and creates file. After we create file, we need to send those file to users using unix 'uuencode' command and insert into blob. (we are using uuencode because of some security reasons otherwise we would have used rwservlet to send the mails directly from report server). So, in the after report trigger, we are updating the report status... since the status will be 'running report in afterreport trigger' we need something which will do an update after executing that report trigger. So, we have created the above job which will do an update after the job is finished (either successful or failure).
February 18, 2005 - 2:17 pm UTC
remove the COMMIT -- why would you commit???? please why would you commit?
let the transaction commit
and then the job will run.
what if the update that fired the trigger rolls back? now you have a job running that should not have run.
If you have 2 rows you update in that table -- how many times might that trigger fire at most? (hint: the answer is NOT 2, it is not 0, it is not 1 -- it is some positive number greater than 2 -- for a 2 row update)
*lose the commit*, you do not need it, you do not want it!
please ignore 'commit' in the above code as I was part of my testing.. Thanks
Jignesh, February 18, 2005 - 10:40 am UTC
February 18, 2005 - 2:19 pm UTC
then remove the autonomous transaction!!!!!!!
Thanks
Jignesh, February 21, 2005 - 10:00 am UTC
Thanks Tom... I have removed Autonomous Transaction part from trigger now... I have implemented code like yours.
Changing of next run time
Ram, February 07, 2006 - 4:18 am UTC
Hi Tom,
I have scheduled some procedures to run at 02.45 AM, but, now I want to reschedule to run at different times, so I am giving the following command
dbms_job.change(jobid, null, trunc(sysdate)+1+1/24, 'trunc(sysdate)+1+1/24');
(To run daily at 01.00 AM)And, similarly, I have changed for other jobs also.
and when I query dba_jobs, I am able to see the changed time, but, the job runs only at 02.45 AM everyday. What could be the problem?
February 07, 2006 - 5:44 am UTC
show us the last_date, this_date, next_date, interval for these jobs (and of course, use a date format that shows us the TIME bit as well as the date)
Altering the next_date
Ram, February 08, 2006 - 3:44 pm UTC
Please check the last_date, this_date....
JOB LAST_DATE THIS_DATE NEXT_DAT INTERVAL
45 2/8/2006 2:44:04 AM 2/9/2006 2:44:04 AM SYSDATE + 1
46 2/8/2006 2:44:04 AM 2/9/2006 2:44:04 AM SYSDATE + 1
44 2/8/2006 2:44:04 AM 2/9/2006 2:44:04 AM SYSDATE + 1
62 2/8/2006 2:44:04 AM 2/9/2006 2:44:04 AM SYSDATE + 1
61 2/8/2006 2:44:04 AM 2/9/2006 2:44:04 AM SYSDATE + 1
I would like to change the next_date to different timings
Regards,
Ram
February 10, 2006 - 8:49 am UTC
it would appear to me, that you did not run the dbms_job.change (and that the interval was not correct in the past - it was sysdate+1 which would cause the job to slide over time)
if you do something like this:
ops$tkyte@ORA10GR2> alter session set nls_date_format = 'dd-mon-yyyy hh24:mi:ss';
Session altered.
ops$tkyte@ORA10GR2> exec dbms_job.submit( :n, 'null;', trunc(sysdate)+1+1/24*2+1/24/60*45, 'trunc(sysdate)+1+1/24*2+1/24/60*45' );
PL/SQL procedure successfully completed.
ops$tkyte@ORA10GR2> commit;
Commit complete.
ops$tkyte@ORA10GR2> select last_date, this_date, next_date, interval from user_jobs;
LAST_DATE THIS_DATE NEXT_DATE INTERVAL
-------------------- -------------------- -------------------- ---------------------
11-feb-2006 02:45:00 trunc(sysdate)+1+1/24
*2+1/24/60*45
ops$tkyte@ORA10GR2> exec dbms_job.change(:n, null, trunc(sysdate)+1+1/24, 'trunc(sysdate)+1+1/24');
PL/SQL procedure successfully completed.
ops$tkyte@ORA10GR2> commit;
Commit complete.
ops$tkyte@ORA10GR2> select last_date, this_date, next_date, interval from user_jobs;
LAST_DATE THIS_DATE NEXT_DATE INTERVAL
-------------------- -------------------- -------------------- ---------------------
11-feb-2006 01:00:00 trunc(sysdate)+1+1/24
what do you see (and please, make sure columns line up - I cannot tell what fields are which)
Changing of next date
Ram, February 12, 2006 - 3:10 pm UTC
Thanks, it is working now. I probably had forgotten to commit
Unable to run dbms_stats
Kumar, May 05, 2006 - 10:17 am UTC
Hi,
I want to schedule stats gathering to every Saturday. I have created a job like this:
var jobno number;
begin
dbms_job.submit(:jobno, 'sys.dbms_stats.gather_schema_stats( ownname=>''SCOTT'', cascade=>TRUE);',next_day(trunc(sysdate),'SATURDAY')+22/24, 'next_day(trunc(sysdate),''SATURDAY'')+22/24');
commit;
end;
But, I am getting the error
Errors in file /ford/app/oracle/admin/FLEETDV/bdump/fleetdv_j000_7835.trc:
ORA-12012: error on auto execute of job 3
ORA-20000: Insufficient privileges to analyze an object in Schema
ORA-06512: at "SYS.DBMS_STATS", line 10583
ORA-06512: at "SYS.DBMS_STATS", line 10751
ORA-06512: at "SYS.DBMS_STATS", line 10805
ORA-06512: at "SYS.DBMS_STATS", line 10782
ORA-06512: at line 1
and in the trace file
ORA-12012: error on auto execute of job 3
ORA-20000: Insufficient privileges to analyze an object in Schema
ORA-06512: at "SYS.DBMS_STATS", line 10583
ORA-06512: at "SYS.DBMS_STATS", line 10751
ORA-06512: at "SYS.DBMS_STATS", line 10805
ORA-06512: at "SYS.DBMS_STATS", line 10782
ORA-06512: at line 1
I have 'Analyze Any' privilege granted through a role.
Also, I am gathering statistics of another schema (SCOTT) through the job. I am able to execute this procedure directly
SQL> execute dbms_stats.gather_schema_stats( ownname=>'SCOTT', cascade=>TRUE);
PL/SQL procedure successfully completed.
What could be wrong ?
May 05, 2006 - 2:47 pm UTC
no roles here - need a direct grant.
create table msg ( id number, x varchar2(50) );
create sequence s;
exec insert into msg values ( s.nextval, 'session = ' || userenv('sessionid') ); for x in ( select * from session_roles ) loop insert into msg values ( s.nextval, 'role = ' || x.role ); end loop;
variable n number
begin
dbms_job.submit( :n,
q'|
insert into msg values ( s.nextval, 'session = ' || userenv('sessionid') ); for x in ( select * from session_roles ) loop insert into msg values ( s.nextval, 'role = ' || x.role ); end loop;
|' );
end;
/
commit;
that'll show you - no roles in the job when it runs.
Unable to run dbms_stats
Kumar, May 05, 2006 - 10:23 am UTC
Hi,
I want to schedule stats gathering to every Saturday. I have created a job like this:
var jobno number;
begin
dbms_job.submit(:jobno, 'sys.dbms_stats.gather_schema_stats( ownname=>''SCOTT'', cascade=>TRUE);',next_day(trunc(sysdate),'SATURDAY')+22/24, 'next_day(trunc(sysdate),''SATURDAY'')+22/24');
commit;
end;
But, I am getting the error
Errors in file /ford/app/oracle/admin/FLEETDV/bdump/fleetdv_j000_7835.trc:
ORA-12012: error on auto execute of job 3
ORA-20000: Insufficient privileges to analyze an object in Schema
ORA-06512: at "SYS.DBMS_STATS", line 10583
ORA-06512: at "SYS.DBMS_STATS", line 10751
ORA-06512: at "SYS.DBMS_STATS", line 10805
ORA-06512: at "SYS.DBMS_STATS", line 10782
ORA-06512: at line 1
and in the trace file
ORA-12012: error on auto execute of job 3
ORA-20000: Insufficient privileges to analyze an object in Schema
ORA-06512: at "SYS.DBMS_STATS", line 10583
ORA-06512: at "SYS.DBMS_STATS", line 10751
ORA-06512: at "SYS.DBMS_STATS", line 10805
ORA-06512: at "SYS.DBMS_STATS", line 10782
ORA-06512: at line 1
I have 'Analyze Any' privilege granted through a role.
Also, I am gathering statistics of another schema (SCOTT) through the job. I am able to execute this procedure directly
SQL> execute dbms_stats.gather_schema_stats( ownname=>'SCOTT', cascade=>TRUE);
PL/SQL procedure successfully completed.
What could be wrong ?