删除Oracle数据库中的已连接用户

时间:2013-03-27 17:03:55

标签: oracle

我想使用sqlplus删除Oracle DB中的一些用户但是我收到错误:

SQL> DROP USER test CASCADE;
DROP USER test CASCADE
*
ERROR at line 1:
ORA-01940: cannot drop a user that is currently connected

我按照SO中的链接查找会话 - Dropping a connected user from an Oracle 10g database schema

但是当我运行命令时,我没有得到任何结果:

SQL> select sid,serial# from v$session where username = 'test';

no rows selected

请帮助我解决在这种情况下如何撤销用户的问题。

13 个答案:

答案 0 :(得分:64)

用户是v$session(和数据字典视图)中的所有大写字母。如果你与大写字母匹配,你应该找到要杀的会话。

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
 /

为用户TEST传递实际的SID和SERIAL#值,然后删除用户......:

ALTER SYSTEM KILL SESSION '<SID>, <SERIAL>'
/

答案 1 :(得分:26)

解决方案:

sql>Shutdown immediate;

sql>startup restrict;

sql>drop user TEST cascade;

如果要重新激活数据库,请重置服务器或:

sql>Shutdown immediate;

sql>startup;

:)

答案 2 :(得分:4)

查询:

SELECT * FROM v$session s;

找到您的用户并执行下一个查询(使用适当的参数):

ALTER SYSTEM KILL SESSION '<SID>, <SERIAL>';

答案 3 :(得分:2)

转到管理工具中的服务并选择oracleserviceSID并重新启动它

答案 4 :(得分:2)

使用以下程序解决了问题:

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;
/

答案 5 :(得分:1)

我试图按照这里描述的流程 - 但没有运气完全杀死会话..然后我喜欢这里的额外步骤:
http://wyding.blogspot.com/2013/08/solution-for-ora-01940-cannot-drop-user.html

我做了什么:
 1. select 'alter system kill session ''' || sid || ',' || serial# || ''';' from v$session where username = '<your_schema>'; - 如下所述。
输出将是这样的:
alter system kill session '22,15' immediate;
 2. alter system disconnect session '22,15' IMMEDIATE ; - 22-sid,15-serial - 从上一个命令重复每个返回会话的命令
    3.重复步骤1-2,而select...不返回空表
    4.打电话     drop user...

错过了什么 - 为alter system disconnect session '22,15' IMMEDIATE ;

返回的每个会话调用select 'alter system kill session '..

答案 6 :(得分:0)

我遇到了同样的问题,默认情况下Oracle配置会影响字母寄存器。确切地说,我的Scheme_Name写成了所有大写字母。您可以在&#34;其他用户&#34;上看到您的Scheme_Name。选项卡,如果您使用的是Oracle S

答案 7 :(得分:0)

以下是我在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

答案 8 :(得分:0)

基本上我认为杀死所有会话应该是解决方案,但是......

我发现了类似的讨论 - https://community.oracle.com/thread/1054062我的问题,那就是我没有为这些用户开会,但我仍然收到错误。我还尝试了第二个最好的答案:

sql>Shutdown immediate;

sql>startup restrict;

sql>drop user TEST cascade;

最终对我有用的是以用户身份登录,手动删除所有表格 - 选择创建drop语句

select 'drop table ' || TABLE_NAME || ';'  from user_tables;

(由于参考,需要多次重新运行)

我不知道这是如何相关的,我还删除了函数和序列(因为这就是我在模式中的所有内容)

当我这样做并且我退出时,我在v$session表中有几个会话,当我杀了那些会话时我就放弃了用户。

我的数据库仍然以限制模式启动(不确定是否重要)。

可以帮助别人。

BTW:我的Oracle版本是Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production

答案 9 :(得分:0)

如果使用RAC,则需要使用GV$*视图而不是V$*。 尝试通过

查找会话
select * from gv$session where username = 'test';

然后您可以终止会话

alter system kill session 'sid, serial#, @inst_id' immediate;

答案 10 :(得分:0)

有时Oracle drop user需要花费很长时间才能执行。在这种情况下,用户可能已连接到数据库。更好的是,您可以终止用户会话并删除用户。

SQL> select 'alter system kill session ''' || sid || ',' || serial# || ''' immediate;' from v$session where username ='&USERNAME';

SQL> DROP USER barbie CASCADE;

答案 11 :(得分:0)

这可以很简单:

SQL> ALTER SYSTEM ENABLE RESTRICTED SESSION;

SQL> DROP USER test CASCADE;

SQL> ALTER SYSTEM DISABLE RESTRICTED SESSION;

答案 12 :(得分:0)

//'SYS' is username from where you wanted to kill session'
SELECT * FROM DBA_TAB_PRIVS WHERE GRANTEE = 'SYS';

**Step 1:**

CREATE OR REPLACE PROCEDURE sys.kill_session(p_sid NUMBER, p_serial NUMBER)
AS
v_user VARCHAR2(30);
BEGIN
SELECT MAX(username)
INTO v_user
FROM v$session
WHERE sid = p_sid
AND serial# = p_serial;
**Step 2**
create or replace procedure kill_session( p_sid in number, p_serial# in number)
 is v_count pls_integer;
 BEGIN
 select count(*) into v_count
 from V$session
 where username = 'SYS'
 and sid = p_sid
 and serial# = p_serial# ;
 if ( v_count = 1 )
 then
 execute immediate '
 alter system kill session ''' ||
 to_char(p_sid,'999999')||','||
 to_char(p_serial#,'999999')||'''';
 else
 raise_application_error( -20001,
 'You do not own session ''' ||
 p_sid || ',' || p_serial# ||
 '''' );
end if;
 END;
 /
 
**Step 3**
 grant execute on kill_session to SYS;
**Step 4**
select inst_id, sid, serial#, username, action, program, service_name, con_id from gv$session where username like 'FCM_469';
Check there will be no sessions now
**Step 5**
DROP USER USER_345 CASCADE;
Output:User Dropped