1

考虑一个具有大量过期用户帐户的 Oracle 11gR2 数据库。我想在不更改任何密码的情况下重新启用所有用户帐户。

这是一个 SQL 语句,用于创建ALTER USER可以执行以重新启用帐户的 SQL 语句字符串:

select listagg( cmds, ' ' ) within group ( order by rownum )
    as cmd
from (
    select
        'alter user "' || d.username || '"' ||
            ' identified by values ''' || u.password || '''' ||
            ' account unlock;'
    as
        cmds
    from
        dba_users d, sys.user$ u
    where
        d.user_id = u.user#
);

此查询的结果是一个字符串,其中包含如下所示的条目:

alter user "USERNAME" identified by values '1234567890ABCDEF' account unlock; ...

我确信可以创建一个 PL/SQL 过程来将此查询的结果存储到一个变量中,然后调用EXECUTE IMMEDIATE [var],但是是否可以通过一些 SQL 语法魔术来EXECUTE IMMEDATE简单地执行由SELECT语句创建的字符串?

4

2 回答 2

2

您不需要存储过程,可以使用匿名 PL/SQL 块:

DECLARE
   stmt varchar(5000);
   cursor get_users
   is
    select d.username, u.password
    from dba_users d
        join sys.user$ u d.user_id = u.user#
    where lock_date is not null;
   user_rec get_users%rowtype;

BEGIN
    FOR user_rec in get_users loop
    BEGIN
       stmt := 'alter user "' || user_rec.username || '"' ||
               ' identified by values ''' || user_rec.password || '''' || 
               ' account unlock';
       execute immediate stmt;
     EXCEPTION WHEN others THEN
        dbms_output.put_line('Error unlocking '||user_rec.username);
        dbms_output.put_line(SQLERRM);
     END;
   END LOOP;
END;
/
于 2013-03-04T23:40:02.790 回答
1

像这样生成 SQL 的 SQL 有效,不知道它是否符合您的需求:

sqlplus -s user/pw@db
set heading off
set feedback off 
set pages 0
spool cmd.sql
select ...
spool off
@cmd.sql
于 2013-03-04T23:01:41.997 回答