Je souhaite supprimer certains utilisateurs de la base de données Oracle à l'aide de sqlplus, mais j'obtiens une erreur:
SQL> DROP USER test CASCADE;
DROP USER test CASCADE
*
ERROR at line 1:
ORA-01940: cannot drop a user that is currently connected
J'ai suivi le lien dans SO pour connaître les sessions - Suppression d'un utilisateur connecté à partir d'un schéma de base de données Oracle 10g
Mais lorsque j'ai exécuté la commande, je n'ai aucun résultat:
SQL> select sid,serial# from v$session where username = 'test';
no rows selected
S'il vous plaît, aidez-moi à supprimer les utilisateurs dans ce cas.
Les utilisateurs sont tous en majuscules dans v$session
(et vues du dictionnaire de données). Si vous faites correspondre des capitales, vous devriez trouver votre session à tuer.
SELECT s.sid, s.serial#, s.status, p.spid
FROM v$session s, v$process p
WHERE s.username = 'TEST' --<<<--
AND p.addr(+) = s.paddr
/
Transmettez les valeurs SID et SERIAL # réelles pour l'utilisateur TEST, puis supprimez l'utilisateur ...:
ALTER SYSTEM KILL SESSION '<SID>, <SERIAL>'
/
Solution :
sql>Shutdown immediate;
sql>startup restrict;
sql>drop user TEST cascade;
Si vous souhaitez réactiver la base de données normalement, réinitialisez le serveur ou:
sql>Shutdown immediate;
sql>startup;
:)
Faire une requête:
SELECT * FROM v$session s;
Recherchez votre utilisateur et effectuez la requête suivante (avec les paramètres appropriés):
ALTER SYSTEM KILL SESSION '<SID>, <SERIAL>';
Le problème a été résolu en utilisant la procédure ci-dessous:
DECLARE
v_user_exists NUMBER;
user_name CONSTANT varchar2(20) := 'SCOTT';
BEGIN
LOOP
FOR c IN (SELECT s.sid, s.serial# FROM v$session s WHERE upper(s.username) = user_name)
LOOP
EXECUTE IMMEDIATE
'alter system kill session ''' || c.sid || ',' || c.serial# || ''' IMMEDIATE';
END LOOP;
BEGIN
EXECUTE IMMEDIATE 'drop user ' || user_name || ' cascade';
EXCEPTION WHEN OTHERS THEN
IF (SQLCODE = -1940) THEN
NULL;
ELSE
RAISE;
END IF;
END;
BEGIN
SELECT COUNT(*) INTO v_user_exists FROM dba_users WHERE username = user_name;
EXIT WHEN v_user_exists = 0;
END;
END LOOP;
END;
/
J'essayais de suivre le flux décrit ici - mais je n'ai pas eu la chance de tuer complètement la session .. Ensuite, j'aime l'étape supplémentaire suivante:
http://wyding.blogspot.com/2013/08/solution-for-ora-01940-cannot-drop-user.html
Ce que j'ai fait:
1. select 'alter system kill session ''' || sid || ',' || serial# || ''';' from v$session where username = '<your_schema>';
- comme décrit ci-dessous.
Out mis sera quelque chose comme ça:alter system kill session '22,15' immediate;
2. alter system disconnect session '22,15' IMMEDIATE ;
- 22-sid, 15-serial - répétez la commande pour chaque session renvoyée de la commande précédente
3. Répétez les étapes 1 et 2 sans que select...
ne renvoie une table vide.
4. Appelez drop user...
Ce qui a été manqué - appelez alter system disconnect session '22,15' IMMEDIATE ;
pour chaque session renvoyée par select 'alter system kill session '..
accédez aux services dans les outils d'administration, sélectionnez oracleserviceSID et redémarrez-le
Voici comment je "automatise" Suppression des utilisateurs connectés dans la base de données Oracle:
# A Shell script to Drop a Database Schema, forcing off any Connected Sessions (for example, before an Import)
# Warning! With great power comes great responsibility.
# It is often advisable to take an Export before Dropping a Schema
if [ "$1" = "" ]
then
echo "Which Schema?"
read schema
else
echo "Are you sure? (y/n)"
read reply
[ ! $reply = y ] && return 1
schema=$1
fi
sqlplus / as sysdba <<EOF
set echo on
alter user $schema account lock;
-- Exterminate all sessions!
begin
for x in ( select sid, serial# from v\$session where username=upper('$schema') )
loop
execute immediate ( 'alter system kill session '''|| x.Sid || ',' || x.Serial# || ''' immediate' );
end loop;
dbms_lock.sleep( seconds => 2 ); -- Prevent ORA-01940: cannot drop a user that is currently connected
end;
/
drop user $schema cascade;
quit
EOF
J'ai eu le même problème, config Oracle affecte par défaut le registre des lettres. Dans exactement mon Scheme_Name a été écrit toutes les lettres capitales. Vous pouvez voir votre nom de schéma sous l’onglet "Autres utilisateurs", si vous utilisez Oracle S.
Fondamentalement, je crois que tuer toutes les sessions devrait être la solution, mais ...
J'ai trouvé une discussion similaire - https://community.Oracle.com/thread/1054062 à mon problème et c'est que je n'ai pas eu de session pour cet utilisateur, mais j'ai quand même reçu l'erreur. J'ai aussi essayé en second la meilleure réponse:
sql>Shutdown immediate;
sql>startup restrict;
sql>drop user TEST cascade;
À la fin, ce qui a fonctionné pour moi a été de me connecter en tant qu’utilisateur, de supprimer toutes les tables manuellement.
select 'drop table ' || TABLE_NAME || ';' from user_tables;
(Doit être ré-exécuté plusieurs fois à cause des références)
Je ne sais pas du tout comment ça se rapporte, j'ai aussi laissé tomber des fonctions et des séquences (parce que c'était tout ce que j'avais dans le schéma)
Quand j'ai fait cela et que je me suis déconnecté, j'ai eu plusieurs sessions dans la table v$session
et lorsque j'ai tué celles-ci, j'ai pu supprimer un utilisateur.
Ma base de données a encore été démarrée en mode restreint (vous ne savez pas si c'est important ou pas).
Peut aider quelqu'un d'autre.
BTW: ma version Oracle est Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production