1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
| create or replace procedure Progress_Bar
As
rindex pls_integer := -1;
slno pls_integer;
Begin
-----------------------------------------------------
-- procedure that does nothing else than waiting --
-- to illustrate the ProgressBar Forms sample --
-----------------------------------------------------
dbms_application_info.set_session_longops(
RINDEX => rindex
,SLNO => slno
,OP_NAME => ' proc_traitement'
,SOFAR => 0
,TOTALWORK => 100
);
-- simulating the task progress --
For i IN 1..100 loop
DBMS_LOCK.SLEEP(.3);
dbms_application_info.set_session_longops(
RINDEX => rindex
,SLNO => slno
,OP_NAME => ' proc_traitement'
,SOFAR => i
,TOTALWORK => 100
);
End loop;
End;
La boucle permet de simuler une procédure d' une minute.
L'index (SOFAR) est mis à jour environ chaque seconde.
Remarque: Le droit d'exécution du package dbms_lock est attribué par SYS
sql > grant execute on dbms_lock to nom_user;
3. Le code Forms
Declare
v_jobname Varchar2(30) := 'PROGRESS_BAR_JOB' ;
v_jobid Number := 12345 ;
v_percent Number := 0 ;
v_end Exception ;
v_version Number := 9 ;
v_nb Pls_integer ;
v_pass Pls_integer := 0 ;
begin
-- Lancement de la procédure par le package dbms_job pour la version 9i --
If v_version = 9 Then
dbms_job.isubmit(v_jobid,' proc_traitement',sysdate,null);
forms_ddl('commit') ;
Else
-- Lancement de la procédure par le package dbms_scheduler pour la version 10g --
dbms_scheduler.create_job(
job_name => v_jobname
,job_type => 'stored_procedure'
,job_action => ' proc_traitement'
,start_date => SYSDATE
,enabled => TRUE
);
End if ;
-- le job tourne ? --
Loop
If v_version = 9 Then
Select count(job)
Into v_nb
From user_jobs
Where job= v_jobid
And total_time!=0;
Else
Select count(*)
Into v_nb
From USER_SCHEDULER_JOBS
Where JOB_NAME = v_jobname;
End if ;
v_pass := v_pass + 1 ;
If v_pass > 100 Then
-- le job ne se lance pas --
message('Problème de lancement du job',acknowledge);
Raise Form_Trigger_Failure ;
End if ;
exit when v_nb > 0 ;
dbms_lock.sleep(.2);
End loop ;
set_item_property('blo_progress.progressbar', width, 0);
v_percent :=0;
-- pour suivre la progression de l'éxecution de procedure --
Loop
Exit when v_percent >= 100;
Select (sofar / totalwork) * 100
Into v_percent
From v$session_longops
Where opname = ' proc_traitement' and sofar < totalwork;
:blo_progress.progressbar:= v_percent||'%';
set_item_property('blo_progress.progressbar',width, round( v_percent*2,2));
synchronize;
End loop;
raise v_end ;
Exception
When NO_DATA_FOUND then
set_item_property('blo_progress.progressbar', width, 200);
:blo_progress.progressbar:= '100%';
raise v_end ;
When TOO_MANY_ROWS then
raise v_end ;
When v_end then
If v_version = 10 Then
DBMS_SCHEDULER.drop_job (job_name => v_jobname,FORCE=> true) ;
End if ;
When Others then
If v_version = 10 Then
DBMS_SCHEDULER.drop_job (job_name => v_jobname,FORCE=> true) ;
End if ;
End; |
Partager