oracle:获取session的IP地址

方法1


创建触发器:

create orreplace trigger login_on

alfterlogon on database

begin

dbms_application_info.set_client_info(sys_context('userenv','ip_address'));

end;

/



这样以后在连接到DB的session,就会自动在v$session动态视图的client_info列记录session的IP地址了。

从V$SESSION中只能得到机器名, 而通过机器名不能确定到具体的机器. 所以必须得到IP
在oracle中的v$session视图中可以保存有会话的想关信息,包括了客户端的大部分连接信息。其中我们可以将会话的发起ip地址写入到client_identifier和client_info
上文中我们提到了使用userenv函数或者sys_context函数可以获得当前会话的相关信息,其中就包含的有ip_address这一项
当我们使用client_identifier字段来保存登录会话的ip地址的时候,我们需要用到dbms_session.set_identifier过程/函数
当我们使用client_info字段来保存登陆会话的ip地址的时候,我们需要用到dbms_application_info.set_client_info过程/函数


例:查看当前用户的ip地址:
MAI@test > select sys_context('userenv','ip_address') from dual;
SYS_CONTEXT('USERENV','IP_ADDRESS')
-------------------------------------
192.168.77.1


MAI@test > select username,sid,serial#,client_info,client_identifier from v$session where sid=(select sys_context('userenv','sid') from dual);
USERNAME            SID    SERIAL# CLIENT_INFO          CLIENT_IDENTIFIER
--------------- ------- ---------- -------------------- --------------------
MAI                 138      38266
使用client_identifier字段
MAI@test > exec dbms_session.set_identifier(sys_context('userenv','ip_address'));
MAI@test > select username,sid,serial#,client_info,client_identifier from v$session where sid=(select sys_context('userenv','sid') from dual);
USERNAME            SID    SERIAL# CLIENT_INFO          CLIENT_IDENTIFIER
--------------- ------- ---------- -------------------- --------------------
MAI                 138      38270                      192.168.77.1
使用client_info字段
MAI@test > exec dbms_application_info.set_client_info(sys_context('userenv','ip_address'));
MAI@test > select username,sid,serial#,client_info,client_identifier from v$session where sid=(select sys_context('userenv','sid') from dual);
USERNAME            SID    SERIAL# CLIENT_INFO          CLIENT_IDENTIFIER
--------------- ------- ---------- -------------------- --------------------
MAI                 138      38270 192.168.77.1         192.168.77.1


当然,这个过程过程可以通过一个触发器来调用,当每一个新的用户连接开启的时候自动触发该触发器,将相应的ip信息写入v$session的相应字段。
触发器的例子:
create or replace trigger on_login_trigger
after logon on database
begin
dbms_application_info.set_client_info(sys_context('USERENV','IP_ADDRESS'));
end;
/
建立这个trigger需要有dba权限,这样的话,当每个用户新登录的时候,这个触发器就会起作用,然后就能够将客户端的ip地址填充到v$session视图中的client_info字段中:
MAI@test > select username,sid,serial#,client_info,client_identifier from v$session where sid=(select sys_context('userenv','sid') from dual);
USERNAME            SID    SERIAL# CLIENT_INFO          CLIENT_IDENTIFIER
--------------- ------- ---------- -------------------- --------------------
MAI                 149        425 192.168.77.1

方法2


利用sys_context函数我们可以获得当前session的hostname和ip address

SQL> selectsys_context('userenv','host') from dual;

SYS_CONTEXT('USERENV','HOST')
--------------------------------------------------------------
WORKGROUP\IBM-L3YMBNP

SQL> select sys_context('userenv','ip_address') from dual;

SYS_CONTEXT('USERENV','IP_ADDRESS')
-----------------------------------------------------------
127.0.0.1

通过sys_context我们只能获得当前session的信息,如果要获得其他session呢?
这个时候我们就用utl_inaddr包来获取

SQL> selectutl_inaddr.get_host_address('IBM-L3YMBNP') from dual;

UTL_INADDR.GET_HOST_ADDRESS('IBM-L3YMBNP')
-------------------------------------------------------------------
9.181.142.152

而且我们还可以获得sina以及其他web site的ip
SQL> select utl_inaddr.get_host_address('www.sina.com.cn') from dual;

UTL_INADDR.GET_HOST_ADDRESS('WWW.SINA.COM.CN')
---------------------------------------------------------------------
218.30.108.55

其原理是:首先获取域名解析服务器(resolv.conf),在根据host.conf文件确定解析顺序,因为缺省的是hosts文件优先解析,这个时候会又继续读取/etc/hosts文件。

如果hosts文件存在解析关系,则返回信息;如果不存在,则继续问询DNS服务器,获得解析地址,如果不能解析,则会出错
SQL> select utl_inaddr.get_host_address('www.a.com') from dual;
select utl_inaddr.get_host_address('www.a.com') from dual
       *
ERROR 位于第 1 行:
ORA-29257: 未知的主机www.a.com
ORA-06512: 在"SYS.UTL_INADDR", line 35
ORA-06512: 在"SYS.UTL_INADDR", line 40
ORA-06512: 在line 1

基本上就是这样了。

猜你喜欢

转载自juji1010.iteye.com/blog/1701952