Oracle
 sql >> Database >  >> RDS >> Oracle

È possibile uccidere una singola query in Oracle senza uccidere la sessione?

Ho trovato un trucco. Non ho idea di quanto sia sicuro giocarci, ma funziona. Esiste un evento Oracle, 10237, descritto come "simula ^C (a scopo di test)".

Devi avere il SID e il SERIAL# della sessione che vuoi interrompere.

Chiama SYS.DBMS_SYSTEM.SET_EV( side , numero di serie , 10237, 1, '' ) per attivare l'evento nella sessione di destinazione. Qualsiasi istruzione attualmente in esecuzione dovrebbe essere interrotta (ricevendo "ORA-01013:l'utente ha richiesto l'annullamento dell'operazione in corso"). Finché l'evento è impostato, qualsiasi ulteriore istruzione che la sessione tenta di eseguire terminerà immediatamente con lo stesso errore.

Per disattivare l'evento, effettuare la stessa chiamata con il quarto parametro impostato a "0". La sessione sarà quindi in grado di eseguire nuovamente le istruzioni.

Si noti che la sessione di destinazione deve rilevare che l'evento è impostato, il che potrebbe richiedere tempo o potrebbe non verificarsi mai, a seconda di ciò che sta facendo. Quindi non puoi semplicemente attivare e disattivare rapidamente l'evento. Dovresti accenderlo, verificare che l'istruzione in questione si sia interrotta, quindi disattivarlo.

Ecco un codice di esempio. Questo è pensato per essere eseguito come blocco anonimo in SQLPlus, con le variabili di sostituzione "sid" e "serial" definite in modo appropriato. Potresti trasformarlo in una stored procedure con quelli come parametri.

DECLARE
  l_status  v$session.status%TYPE;
BEGIN

  dbms_system.set_ev( &sid, &serial, 10237, 1, '');

  LOOP
    SELECT status INTO l_status FROM v$session
      WHERE sid = &sid and serial# = &serial;
    EXIT WHEN l_status='INACTIVE';
  END LOOP;

  dbms_system.set_ev( &sid, &serial, 10237, 0, '');
END;