Oracle
 sql >> Base de données >  >> RDS >> Oracle

Est-il possible de tuer une seule requête dans Oracle sans tuer la session ?

J'ai trouvé une astuce. Je ne sais pas à quel point c'est sûr de jouer avec, mais ça marche. Il existe un événement Oracle, 10237, qui est décrit comme "simuler ^C (à des fins de test)".

Vous devez avoir le SID et le SERIAL# de la session que vous souhaitez interrompre.

Appelez SYS.DBMS_SYSTEM.SET_EV( sid , numéro de série , 10237, 1, '' ) pour activer l'événement dans la session cible. Toute instruction en cours d'exécution doit être interrompue (réception "ORA-01013 :l'utilisateur a demandé l'annulation de l'opération en cours"). Tant que l'événement est défini, toute autre instruction que la session tente d'exécuter se terminera immédiatement avec la même erreur.

Pour désactiver l'événement, effectuez le même appel avec le quatrième paramètre réglé sur "0". La session pourra alors exécuter à nouveau des instructions.

Notez que la session cible doit détecter que l'événement est défini, ce qui peut prendre du temps ou ne jamais se produire, selon ce qu'elle est en train de faire. Vous ne pouvez donc pas simplement activer et désactiver rapidement l'événement. Vous devrez l'activer, vérifier que l'instruction en question s'est arrêtée, puis l'éteindre.

Voici un exemple de code. Ceci est destiné à être exécuté comme un bloc anonyme dans SQLPlus, avec les variables de substitution "sid" et "serial" définies de manière appropriée. Vous pouvez le transformer en une procédure stockée avec ceux-ci comme paramètres.

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;