公司测试环境总是出现一些测试用户试用了以后没人管理,造成空间大量浪费,DBA想进行删除时候又不知道是否可以删除,我想通过建立登陆触发器,然后定期将这种测试用户lock。当创建新的用户时候,看见lock的用户就可以删除了。
首先创建登陆表,登陆表根据你想得到的信息来创建,
-- Create table
create table LOGON
(
USERNAME VARCHAR2(100),
LOGON_DATE DATE,
V_PROGREAM_NAME VARCHAR2(200),
V_IP VARCHAR2(1000)
)
我所想到的是登录名,登录时间,登录的程序,登陆ip地址
你可以根据自己需要添加,但是我想不出来了。
创建登陆触发器
CREATE OR REPLACE TRIGGER insert_logon
AFTER LOGON ON DATABASE
declare
v_program_name varchar2(200);
v_username varchar2(100);
logon_date date;
v_ip_address varchar2(1000);
begin
--获取当前的连接用户信息
select username,logon_time,program,SYS_CONTEXT('USERENV','IP_ADDRESS')
into v_username,logon_date,v_program_name,v_ip_address
from (
select *
from v$session where AUDSID = SYS_CONTEXT('USERENV', 'SESSIONID') and username!='DBSNMP'
order by logon_time desc)
where rownum=1;
--插入登录信息表
insert into logon values(v_username,logon_date,v_program_name,v_ip_address);
commit;
end;
由于10g中DBSNMP用户会查实登陆然后获取数据库快照,所以把这个用户排除出去,其他还有那些要排除的呢?(据观察sysman也可以排除,这两个都是oem用来照快照的)
这样每次登陆都会插入logon表中。
创建存储过程定期lock用户。
由于系统用户不希望锁定,我又没找出那个字段可以标注是否为系统用户,所以我想到了以下三个变通方法。
1、 系统用户就那么10个左右,一个一个写~~~(好傻的办法)
2、 创建一个profile,测试用户全部使用这个profile,然后可以根据这个作为where条件。
3、 所有测试用户都是用一个临时表空间,根据这个作为where条件查询。
另外profile中有一个过期,为啥不用呢,因为做过测试,这个字段的状态是在下次登录时候修改的。也就是说如果22日过期,当我23日如果不用此用户登录时,status状态还为open呢。那人家以后都不登陆这个用户就无法判断了。
有了判断依据就好写了
CREATE OR REPLACE PROCEDURE lock_user IS
user_name varchar(200);
str varchar(1000);
BEGIN
select a.username
into user_name
from dba_users a,
(select username, max(logon_date) last_logon_date
from logon
group by username) b
where
-- account_status ='EXPIRED' and
profile = 'TEST_A'
and a.username = b.username
--and last_logon_date
;
str := 'alter user ' || user_name || ' account lock';
execute immediate (str);
end;
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/9524377/viewspace-630786/ ,如需转载,请注明出处,否则将追究法律责任。