【问题标题】:Oracle: automate dropping and recreating connected userOracle:自动删除和重新创建连接的用户
【发布时间】:2014-10-01 08:20:26
【问题描述】:

我正在尝试使用 Oracle 删除已连接的用户。由于 Oracle 是一款出色的软件产品,这个问题已经被问了超过 7 亿次。但是,我找到的所有答案都需要用户输入,并且无法自动发布。典型的答案在这里很好地说明了:https://stackoverflow.com/a/15665694/177293

我想在脚本中执行此操作,而无需人工干预。所以,我正在尝试这样:

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

我希望有一个看起来像这样的完成脚本:

#!/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

上面有什么问题?

【问题讨论】:

    标签: oracle sqlplus


    【解决方案1】:

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

    但是不要被它骗了,这仍然是一个非常困难的问题。不幸的是,Oracle 系统很少会频繁删除和重新创建用户。这意味着你会遇到很多奇怪的错误。

    我已经构建了脚本来执行此操作,但遗憾的是无法在此处共享它们。以下是您必须期待的一些有趣的事情:

    1. 终止连接的会话。
    2. 正在终止阻止您会话拥有的对象的其他会话。
    3. 截断临时表,因为它们有奇怪的锁定规则。并使用它们终止会话,请参阅如何在 DROP OF TEMPORARY TABLE 期间诊断 ORA-14452(文档 ID 800506.1)。
    4. 在 KILL 语法中使用 INST_ID,用于 RAC。
    5. 在整个过程中循环几次,以防应用程序生成锁定对象的新会话。
    6. 如果您使用的是对象关系代码,请执行dbms_session.reset_package。令人惊讶的是,有些对象即使在删除并重新创建其所有者后仍然存在。

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

    是的,这太荒谬了。 Oracle 在快速创建新数据库的方法上花费了大量精力;可传输的表空间、可插拔的数据库、虚拟化等。您会认为有一种可靠的删除和重新创建用户的好方法!

    【讨论】:

    • 我真的不明白为什么你认为在一个活动系统中删除一个活动用户应该很容易,其对象可能当时实际上正在被应用程序使用。似乎是一件应该很难的事情。
    • 由于您的意图是无论如何都要删除整个架构,因此首先撤销对用户对象的所有授权可能会有所帮助。那么您就不能在其他帐户中拥有锁定这些对象的新会话。
    • @DaveCosta 我明白你的意思,通常很难删除或删除正在使用的东西。但部分问题在于 Oracle 对“活动”的定义很模糊,特别是对于临时表。即使没有任何活动事务,会话也会阻止事物的方式真的很烦人。
    猜你喜欢
    • 2015-01-10
    • 1970-01-01
    • 2010-11-08
    • 2019-07-27
    • 1970-01-01
    • 1970-01-01
    • 2013-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多