首页 文章

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

提问于
浏览
32

我想使用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

在这种情况下,请帮助我如何删除用户 .

9 回答

  • 55

    使用以下程序修复了问题:

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

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

  • 22

    方案:

    sql>Shutdown immediate;
    
    sql>startup restrict;
    
    sql>drop user TEST cascade;
    

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

    sql>Shutdown immediate;
    
    sql>startup;
    

    :)

  • 0

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

  • 1

    查询:

    SELECT * FROM v$session s;

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

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

  • 0

    我试图按照这里描述的流程 - 但没有运气完全杀死会话..然后我喜欢这里的额外步骤:
    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...

    错过了什么 - 为 select 'alter system kill session '.. 返回的每个会话调用 alter system disconnect session '22,15' IMMEDIATE ;

  • 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

  • 1

    以下是我在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
    
  • 1
    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>'
    /
    

相关问题