国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > Oracle > 正文

ORACLE Virtual Private Database 全新體驗

2024-08-29 13:39:06
字體:
來源:轉載
供稿:網友

  在開始對Oracle的Virtual PRivate Database的介紹之前,筆者想就ROW-RULE control(行記錄級訪問控制)的概念簡單地說幾句。
  
  行記錄級訪問控制問題的提出和意義?
  企業的應用系統都離不開數據庫系統,數據庫系統的權限控制是很重要的一個環節,大型數據庫系統(ORACLE、DB2、SYBASE、MS SQLSERVER)都提供完善的用戶治理機制,從而可以嚴密地控制數據庫對象(表、視圖、函數、存儲過程、程序包等等)的訪問。但是,這往往是對象級別的。
  
  隨著商務需求地不斷地提出,出現了對于行記錄控制的要求:
  
  1) 數據查詢和報表輸出數據需要能夠進行有效地隔離,如在一個簡單地銷售數據統計應用中,大區經理、地區經理和銷售員查詢的數據就不同。
  
  2) asp(應用服務供給商)系統出現,在系統結構上,就出現了許多企業用戶的數據都會存放在同一個數據庫種,但是系統需要能夠有效地隔離。
  
  為了滿足這樣的需求,在業務數據表需要中加上一些字段來進行控制,應用的開發往往會另行開發很多代碼來實現行記錄控制。但是,隨著業務的變化,我們會發現開發和維護這種治理需求的成本越來越高。
  
  我們需要尋找一種新的解決方案,能夠使應用系統的架構設計簡單,擴展性強,治理和維護的成本很低。
  
  ORACLE8i的一個新特性Virtual Private Database
  
  ORACLE 8i提供了一個新的特性,來實現行級規則的控制,稱之為Virtual Private Database。充分利用8i提供的Virtual Private Database技術,可以實現,一個數據庫Schema的數據同時給多個數據庫用戶訪問,但是又能很好地隔離各自的數據內容。顯然,這已經不是原來的對象級的控制的概念。
  
  下面是筆者的體驗,寫下來,供大家參考。我先通過一個簡單的例子,來說明ORACLE 8i的這個新特性(需ORACLE 8i的企業版才支持)。
  
  環境:windows 2000 Server + ORACLE 8.1.7(Enterprise Edition)
  
  在SCOTT用戶下,有一個Customers表,記錄著客戶資料,以后為每個客戶分配一個ORACLE數據庫登陸賬號,客戶可以登陸,查詢自己的訂單情況。那么,我們需要做的就是能夠把每個登陸賬號和客戶代碼對應起來。就是說要實現一個映射關系,當然,通過自己建關系映射表,寫代碼做,也可以實現,但是ORACLE 8I把這一切變地非常簡單(我接下來的介紹都會圍繞著ORACLE 8i這項技術是我們的工作如何更加簡單,如何更加輕易控制,請記住,這是筆者寫這篇文章的目的)。
  
  --建立一個SECUSR的賬號,用于權限控制用
  
  connect system/manager@oracle;
  
  create user secusr identified by secusr;
  
  grant connect,resource,dba to secusr;
  
  --把Customers的查詢權利賦予secusr
  
  connect scott/tiger@oracle;
  
  grant select on "Customers" to secusr;
  
  --連接到secusr用戶
  
  connect secusr/secusr@oracle;
  
  --創建上下文
  
  create context Customer_context USING secusr.CUSTOMER_SECURITY_CONTEXT;
  
  --創建程序包customer_security_context
  
  create or replace package
  
  secusr.customer_security_context is
  
  procedure set_customerid;
  
  end;
  
  create or replace package body
  
  secusr.Customer_security_context is
  
  procedure set_customerid is
  
  begin
  
  IF SYS_CONTEXT('USERENV','session_USER')='SCOTT' THEN
  
    DBMS_SESSION.SET_CONTEXT('customer_context','customerid','ALFKI');
  
  END IF;
  
  end;
  
  end;
  
  --授權
  
  grant execute on secusr.Customer_security_context to public;
  
  ORACLE 8i中提供了Context(連接上下文)的概念,類似于asp中的session,你可以為當前這個連接設置多個全局變量,記錄信息,這個信息一直保持到連接被釋放。
上面的代碼,就是為用SCOTT賬號登陸的連接,進行了一次客戶代碼的映射(SCOTT->ALFKI),而且,隨時可以SYS_CONTEXT來查詢。
  
  具體代碼如下:
  
  SQL> connect scott/tiger@oracle;
  
  已連接。
  
  SQL> execute secusr.Customer_security_context.set_customerid;
  
  PL/SQL 過程已成功完成。
  
  SQL> select SYS_CONTEXT('CUSTOMER_CONTEXT','CUSTOMERID') FROM DUAL;
  
  SYS_CONTEXT('CUSTOMER_CONTEXT','CUSTOMERID')
  
  --------------------------------------------------------------------------------
  
  ALFKI
  
  但是,我覺的還不夠,能夠做到每個連接建立的時候,就自動完成這種映射,令人興奮的是,ORACLE 8i提供了系統級的觸發器,讓我輕松地實現。
  
  --SCOTT用戶登陸觸發器
  
  connect system/manager@oracle
  
  CREATE OR REPLACE TRIGGER scott.tg_set_usr_context
  
  AFTER LOGON ON DATABASE
  
  BEGIN
  
  secusr.customer_security_context.set_customerid;
  
  END;
  
  --斷掉connection,重新登陸
  
  Oracle8i Enterprise Edition Release 8.1.7.0.0 - ProdUCtion
  
  With the Partitioning option
  
  JServer Release 8.1.7.0.0 - Production
  
  SQL> CONNECT scott/tiger@oracle
  
  已連接。
  
  SQL> select SYS_CONTEXT('CUSTOMER_CONTEXT','CUSTOMERID') FROM DUAL;
  
  SYS_CONTEXT('CUSTOMER_CONTEXT','CUSTOMERID')
  
  --------------------------------------------------------------------------------
  
  ALFKI
  
  SQL>
  
  好了,夠簡單吧。
  
  采用Virtual Private Database如何達到SQL DML上的數據控制訪問要求呢?
  
  Virtual Private Database技術可以對一張表的記錄設置DML操作的過濾策略。ORACLE8i提供了POLICY的概念,并且為此配備了一套系統程序包,來完成設置。下面,我來介紹一下:
  
  connect secusr/secusr@oracle
  
  --做一個函數,返回對應的過濾條件
  
  create or replace package secusr.customer_security is
  
  function customer_sec
  
  return VARCHAR2;
  
  end;
  
  create or replace package body secusr.customer_security
  
  is
  
  function customer_sec(d1 varchar2,d2 varchar2)
  
  return varchar2
  
  IS
  
  begin
  
  IF SYS_CONTEXT('USERENV','SESSION_USER') IN ('SYS','SYSTEM','SECUSR') THEN
  
    RETURN NULL;
  
  ELSE
  
    RETURN 'customerid=''' SYS_CONTEXT('CUSTOMER_CONTEXT','CUSTOMERID') '''';
  
  END IF;
  
  end;
  
  end;
  
  --設置表數據的分割過濾
  
  EXECUTE DBMS_RLS.ADD_POLICY('SCOTT','"Customers"','Customers_sec_Policy',
  
  'SECUSR',
  
  'customer_security.customer_sec',
  
  'SELECT,UPDATE,DELETE');
  
  customer_security程序包的customer_sec函數實現了,根據但前的CONTEXT中CUSTOMERID的內容,來返回一個過濾的策略,函數的參數形式是固定的。通過dbms_rls程序包的ADD_POLICY過程,把策略條件同表綁定以來,以后,每次select,update,delete都會自動應用這個策略。

  
  好了,現在我們來測試一下
  
  --用SCOTT登陸,只能看到自己的信息
  
  SQL> connect scott/tiger@oracle;
  
  已連接。
  
  SQL> select customerid,city from "Customers";
  
  CUSTOMERID CITY
  
  ---------- ------------------------------
  
  ALFKI   Berlin
  
  --用SYSTEM登陸,可以看到所有的
  
  SQL> connect system/manager@oracle;
  
  已連接。
  
  SQL> select customerid,city from "SCOTT"."Customers";
  
  CUSTOMERID CITY
  
  ---------- ------------------------------
  
  ALFKI   Berlin
  
  ANATR   México D.F.
  
  ANTON   México D.F.
  
  AROUT   London
  
  BERGS   Lule?  D.F.
  
  BLAUS   Mannheim
  
  BLONP   Strasbourg
  
  BOLID   Madrid
  
  BONAP   Marseille
  
  BOTTM   Tsawassen
  
  BSBEV   London
  
  非常好,完全滿足了要求,現在可以放心地把SCOTT賬號給客戶(ALFKI)了,客戶可以查詢自己的訂單情況,當然只能是自己的。
  
  SQL> SELECT a.orderid,a.customerid,a.orderdate,
  
   2 sum(c.UnitPrice*c.Quantity*(1-c.Discount)) as TotalMoney
  
   3 FROM "Orders" a,"Customers" b ,"Order Details" c

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 芜湖市| 阳原县| 邯郸县| 定陶县| 普定县| 彭山县| 新干县| 永年县| 东平县| 西华县| 石泉县| 望谟县| 招远市| 平邑县| 庆元县| 沧州市| 镇安县| 大安市| 丰原市| 阿图什市| 绥江县| 沐川县| 榆树市| 安阳县| 安徽省| 苍南县| 伊吾县| 和林格尔县| 平泉县| 石家庄市| 枞阳县| 翼城县| 灵丘县| 宁南县| 海宁市| 金川县| 宝坻区| 石嘴山市| 宁安市| 新昌县| 龙江县|