Chinaunix首页 | 论坛 | 博客
  • 博客访问: 410861
  • 博文数量: 66
  • 博客积分: 1416
  • 博客等级: 上尉
  • 技术积分: 922
  • 用 户 组: 普通用户
  • 注册时间: 2006-09-16 10:37
个人简介

高級Oracle DBA,善長Linux系統維運以及Oracle數據庫管理,開發,調優. 具有多年PL/SQL開發經驗.

文章分类

全部博文(66)

文章存档

2015年(9)

2014年(4)

2013年(5)

2010年(1)

2009年(3)

2008年(6)

2007年(30)

2006年(8)

我的朋友

分类: Oracle

2015-04-28 14:36:45

 
當有不同的用戶或由不同的系統登入到Oracle系統時,
為便於全局跟蹤該用戶由哪台機器登入的,登入的是哪個系統,登入時間,登入帳戶等.
一般會在登入或切換窗口時用table記錄相關信息.如我們的物控系統中的y3_login
 
y3_login記錄方式有以下問題.
1. insert後需要commit, 可能影響到別的事務. (或可用自治事務)
2. table一般不是全局的, 多個系統無法共用.
3. 網絡中段異常退出時會無法及時清理帳戶信息.
4. 同一ip,同一帳戶多次登入,不便於區分
 
個人建議解決方案如下:  
在Oracle 登入數據字典中有一個欄位v$session.client_info VARCHAR2(64).
不超過64字節的信息可以用 dbms_application_info.set_client_info 來修改保存. 退出或中斷系統會自動清除.
用package  pkg_clientinfo重新封裝,以變於修改信息.

点击(此处)折叠或打开

  1. create or replace package pkg_clientinfo is

  2.  procedure set_info(id varchar2, val varchar2) ;
  3.  function get_info(id varchar2) return varchar2 ;
  4.  
  5. end pkg_clientinfo;

  6.  
  7. /
  8. create or replace package body pkg_clientinfo is

  9. /********
  10. 用分號來隔離不同段信息
  11. ******/
  12. procedure set_info(id varchar2, val varchar2) is
  13. v_info varchar2(64) ;
  14. n_info varchar2(64) ;
  15. BEGIN
  16.    v_info := sys_context('USERENV', 'CLIENT_INFO') ;
  17.    
  18.    for r in (select column_value data from table(func_split(v_info))) loop
  19.       if length(r.data)>1 and substr(r.data, 1, length(id)+1) <> id ||':' then
  20.          n_info := n_info||r.data||';';
  21.       end if ;
  22.    end loop;
  23.    if val is not null then
  24.      n_info := n_info||id||':'||val ;
  25.    end if;
  26.    dbms_application_info.set_client_info(n_info);
  27. END;

  28. function get_info(id varchar2) return varchar2 is
  29.   tmp varchar2(64) ;
  30. begin
  31.   dbms_application_info.read_client_info(tmp) ;
  32.   return substr(regexp_substr(tmp, id||':[^;]+'), length(id)+2);
  33. end ;

  34.  

  35. /*
  36.  select count(*)
  37.  from v$session where type='USER'
  38.  and client_info like '%user:xx%' and client_info like '%m:zc%';
  39. */
  40. end pkg_clientinfo;
  41. /
使用測試:

点击(此处)折叠或打开

  1. pkg_clientinfo.set_info('U','testuser');
  2. pkg_clientinfo.set_info('IP',SYS_CONTEXT('USERENV', 'IP_ADDRESS');

問題點: 只能記錄64個字節. 記錄信息需簡潔.

阿飛
2015/04/28
阅读(4795) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~