Si vous utilisez SQL*Plus, vous savez qu’avec un « [Ctrl]+C », vous pouvez arrêter un ordre SQL sans arrêter votre session, ni votre transaction. Et bien, il est possible de lancer l’équivalent d’un « [Ctrl]+C » sur une autre session que la votre. Il est probablement très déconseillé de s’amuser à ça sur une production mais pour de faux, voici comment faire…
Exemple
Imaginons une requête en cours coûteuse… Lancez une session SQL*Plus et lancez par exemple la séquence d’ordres SQL qui suit :
sqlplus / as sysdba
set timing on
select count(*)
from dba_objects a, dba_objects b;
Lancer un « [Ctrl]+C » depuis une autre session
Lancez une autre session SQL*Plus et déterminez la session active (Attention, dans mon test, je n’ai qu’une session active; dans votre cas, il faudra sans doute filtrer votre requête sur plus de critères ou des critères différents :
sqlplus / as sysdba
col sid format 9999999 new_value sid
col serial# format 9999999 new_value serial
col sql_id format a15 new_value sql_id
select sql_id, sid, serial# from v$session
where status='ACTIVE'
and username is not null
and sid != sys_context('userenv', 'sid')
and program like 'sqlp%';
SQL_ID SID SERIAL#
------------- ---------- ----------
9dtkhfhpgt2sh 125 5
select * from table(dbms_xplan.display_cursor('&&sql_id'));
Une fois la session identifiée, vous pouvez récupérer le PID du process serveur, puis vous attacher avec oradebug
:
col tracefile format a80
set lines 180
col spid format a10 new_value spid
select s.sid, p.spid, p.tracefile
from v$session s, v$process p
where s.paddr=p.addr
and s.sid=&&sid;
SID SPID TRACEFILE
--- ---- -----------------------------------------------------------------
125 2396 /u01/app/oracle/diag/rdbms/black/BLACK/trace/BLACK_ora_2396.trc
oradebug setospid &&spid
Oracle pid: 19, Unix process pid: 2396, image: oracle@arkzoyd (TNS V1-V3)
Pour lancer le [Ctrl]+C, tapez simplement les 2 lignes ci-dessous:
oradebug session_event 10237 trace name context forever, level 1
oradebug session_event 10237 trace name context off;
Dans votre première session, vous voyez apparaître la ligne suivante; votre requête est arrêtée
*
ERROR at line 3:
ORA-01013: user requested cancel of current operation
L’histoire ne dit pas si votre application s’en remettra.
Notes:
1- Si vous n’annulez pas l’event 10237, tous les ordres qui suivent finiront avec la même erreur. C’est peut-être ce que vous recherchez 😉
2- Vous pouvez également envoyer l’event avecdbms_system.set_ev
comme ci-dessous :exec dbms_system.set_ev(&&sid,&&serial,10237,1,'');
exec dbms_system.set_ev(&&sid,&&serial,10237,0,'');