2014-09-30 69 views
2

我正在尝试使用Oracle删除连接的用户。由于Oracle是一款出色的软件产品,因此这个问题已被问及7亿次以上。但是,我发现所有的答案都需要用户输入,并且不能在发布时自动执行。典型的答案在此陈述如下:https://stackoverflow.com/a/15665694/177293Oracle:自动删除并重新创建连接的用户

我想在没有人介入的脚本中这样做。所以,我想是这样的:

BEGIN 
    FOR i IN (
     SELECT sid, serial# from v$session where username = 'MYUSER' 
    ) LOOP 
     EXECUTE IMMEDIATE 'alter system kill session ''' || i.sid || ',' || i.serial# || ''';'; 
    END LOOP; 
END; 

其中,欢快,在在sqlplus结果:

BEGIN 
* 
ERROR at line 1: 
ORA-00911: invalid character 
ORA-06512: at line 5 

尝试一个稍微不同的策略:

BEGIN 
    FOR i IN (
     SELECT 
     'alter system kill session ''' || sid || ',' || serial# || ''';' 
     from v$session where username = 'MYUSER' 
    ) LOOP 
     EXECUTE IMMEDIATE ''|| i ||''; 
    END LOOP; 
END; 

结果:

EXECUTE IMMEDIATE ''|| i ||''; 
         * 
ERROR at line 7: 
ORA-06550: line 7, column 21: 
PLS-00306: wrong number or types of arguments in call to '||' 
ORA-06550: line 7, column 3: 
PL/SQL: Statement ignored 

我希望有af如下所示:

#!/bin/sh 

sqlplus system/manager <<EOT 
BEGIN 
    FOR i IN (
     SELECT sid, serial# FROM v$session WHERE username = 'MYUSER' 
    ) LOOP 
     EXECUTE IMMEDIATE 'alter system kill session ''' || i.sid || ',' || i.serial# || ''';'; 
    END LOOP; 
END; 
DROP USER MYUSER CASCADE; 
DROP TABLESPACE MYUSER INCLUDING CONTENTS AND DATAFILES; 
CREATE USER MYUSER IDENTIFIED BY password; 
ALTER USER MYUSER IDENTIFIED BY password; 
GRANT connect, resource TO MYUSER; 
exit; 
EOT 

上面出现了什么问题?

回答

2

上述脚本的主要问题是;不应处于动态SQL中。

但不要让这个骗过你,这仍然是一个难以置信的难题。不幸的是,Oracle系统很少频繁丢弃和重新创建用户。这意味着你会遇到很多奇怪的错误。

我已经构建了脚本来做到这一点,但不幸的是无法在这里分享它们。这里有一些有趣的事情,你必须期待:

  1. 杀死连接的会话。
  2. 杀死阻塞会话拥有的对象的其他会话。
  3. 截断临时表,因为它们有奇怪的锁定规则。使用它们查看会话,请参阅如何在临时表删除期间诊断ORA-14452(文档ID 800506.1)。
  4. 在KILL语法中使用INST_ID,用于RAC。
  5. 在应用程序产生锁定对象的新会话的情况下循环遍历整个过程几次。
  6. 如果您使用的是对象关系代码,请执行dbms_session.reset_package。令人惊讶的是,即使在丢弃并重新创建其所有者后,一些对象仍然可以坚持。

如果它是一个复杂的应用程序,期望编写大约一百行代码。预计会花费几周的时间来测试一些奇怪的错误。期待它偶尔会失败。

是的,这很荒谬。 Oracle在快速创建新数据库方面花费了大量精力;可移动的表空间,可插拔的数据库,虚拟化等等。你会认为这将是一个可靠地删除和重新创建用户的好方法!

+0

我不明白为什么你认为应该很容易将活动用户放在活动系统中,而活动系统中的对象实际上可能正在被应用程序使用。看起来像是一件应该很难的事情。 – 2014-10-01 02:34:27

+0

既然你的意图是放弃整个架构,也许首先撤销用户对象上的所有授权将会很有帮助。然后,您无法在其他帐户中锁定这些对象的新会话。 – 2014-10-01 02:37:02

+0

@DaveCosta我明白了你的观点,通常很难删除或删除正在使用的内容。但问题的一部分是Oracle对什么是“主动”有模糊的定义,特别是对于临时表。即使在没有任何活动事务的情况下,会话也可以阻止事物,这真的很烦人。 – 2014-10-01 03:18:46