oracle 虚拟专用数据库详细介绍

所谓虚拟专用数据库(VPD)指的是,通过在数据库里进行配置,从而让不同的用户只能查看某个表里的部分数据。VPD分为以下两个级别。

行级别:在该级别下,可以控制某些用户只能查看到某些数据行。比如,对于销售数据表sales 来说,每个销售人员只能检索出他自己的销售数据,不能查询其他销售人员的销售数据。

列级别:在该级别下,可以控制某些用户不能检索某个表的某个列的值。比如用户HR 下的 employees 表中,含有工资(salary)列,由于该列比较敏感,因此不让其他用户查询该列的值。 其他用户检索该列时,会发现其值全都为空(null )。

一、基于行的VPD 

基于行的VPD 也叫作Fine-Grained Access Control ,简称 FGAC 。FGAC 通过定义规则实现,规则 的集合叫做FGAC 政策(policy)。如果对某个表设置了 FGAC ,则当用户对该表发出查询或者DML 语句时,Oracle 都会根据定义的 FGAC 政策,而自动改写这些SQL 语句。其改写方式为自动在SQL 语句后面添加where条件。

比如,我们在OE用户下有一个表sales_list ,存放了所有的销售记录。每个销售人员只能查询他 自己的销售记录。于是,我们在sales 表上设置FGAC 政策来实现这个业务需求。如果某个销售人员 (假设其登录的用户名为 S0020 )发出下面的查询语句:

Select * from sales_list ; 

当Oracle 在执行该语句时,如果发现 sales_list 表上存在FGAC 政策,于是就会根据 FGAC 政策,按照如下方式改写该SQL 语句:

Select * from sales_list where seller_id='S0020'; 

对用户来说,这个添加 where条件的过程是完全透明的,用户并不知道 Oracle 已经改写了他发出的SQL 语句,从而过滤了查询结果。当然,如果该销售人员发出的语句为:

Select * from sales_list where values>1000 ; 

那么,当Oracle 在改写该 SQL 语句时,则会改写为如下形式:

Select * from sales_list where qty_sold>1000 and seller_id='S0020';

使用FGAC 政策来限定返回记录的方式具有许多优点。比如,不需要改写应用程序、对用户完全透明、集中设置、便于管理等。

在使用FGAC 时,会涉及应用程序上下文(Application Context)的概念,使用应用程序上下文可 以简化FGAC 的实现。应用程序上下文是一个数据库对象,可以把它理解为数据库里的每个 session 的全局环境变量。一旦用户登录到数据库,从而创建出session 以后,应用程序上下文就在整个 session 的生命周期里可用。在应用程序上下文里可以定义多个属性,并为这些属性设置具体的值。而用户不 能直接修改属性的值,只能通过程序包来修改属性值。应用程序上下文总是由用户sys 拥有。

比如,对于前面 sales_list 表的例子来说。我们可以创建一个应用程序上下文,当用户登录时,将 该用户的ID 号作为一个属性值放入该应用程序上下文中。然后在定义FGAC 政策的时候,将该用户 ID号取出,并作为限定条件短语(也就是where条件语句)返回给 Oracle,从而实现FGAC 。

在Oracle 数据库里,已经为每个 session 都预先建立了一个应用程序上下文:userenv。一旦建立了session ,该 session 就可以使用这个应用程序上下文。在 userenv中已经预先定义了一些属性,比如 ip_address、session_user和db_name 等。在获取应用程序上下文里的属性值时,我们使用sys_context 函数。该函数包含两个参数,第一个参数表示应用程序上下文的名称,第二个参数表示要显示的属性 名称。如下所示:

SQL> select sys_context('userenv','ip_address') "IP",
   sys_context('userenv','db_name') "DB" from dual;
IP           DB
---------------   ---------
152.68.32.60     ora10g 

我们也可以创建自己的应用程序上下文,如下所示:

SQL> create or replace context sales_ctx using oe.sales_app_pkg;

在这里,sales_ctx 是应用程序上下文的名称,而 sales_app_pkg 则是用来设置sales_ctx 里属性的程序包。在创建应用程序上下文时,指定的、用来设置其中属性的程序包可以不必事先存在。但是在为应用程序上下文里设定属性值时,该程序包必须存在,否则报错。如果要删除应用程序上下文,则使用下面的命令:

SQL> drop context sales _ctx; 

创建了应用程序上下文以后,我们就可以在其中设置属性了。在设置具体的应用程序上下文属性时,必须使用Oracle 提供的程序包 dbms_session.set_context 来设置其属性。其使用格式为:

dbms_session.set_context ('context_name', 'attribute_name', 'attribute_value') 

我们只能在程序包里使用dbms_session.set_context,而不能直接在SQL*Plus里调用。如下所示:

SQL> show user
USER is "SYS"
SQL> exec dbms_session.set_context('sales_ctx','seller_id','S0020');
BEGIN dbms_session.set_context('sales_ctx','seller_id','S0020'); END;
*
ERROR at line 1:
ORA-01031: insufficient privileges
ORA-06512: at "SYS.DBMS_SESSION", line 90
ORA-06512: at line 1 

我们创建oe.sales_app_pkg包,如下所示:

SQL> connect oe/oe
SQL> create or replace package sales_app_pkg is
 2  procedure set_sales_context;
 3 end;
 4 /
SQL> create or replace package body sales_app_pkg is
 2  procedure set_sales_context is
 3  begin
 4  dbms_session.set_context('sales_ctx','seller_id',user);
 5  end;
 6 end;
 7 /
SQL> grant select on sales_list to public;
SQL> grant update on sales_list to public;
SQL> grant execute on sales_app_pkg to public; 

把执行oe.sales_app_pkg 程序包的权限赋给所有用户以后,我们可以测试应用程序上下文是否生效了。

SQL> connect hr/hr
SQL> exec oe.sales_app_pkg.set_sales_context;
SQL> select sys_context('sales_ctx','seller_id') from dual;
SYS_CONTEXT('SALES_CTX','SELLER_ID')
--------------------------------------------------------------------------------
HR 

可以看到,应用程序上下文生效了。接下来,我们创建用于FGAC 规则的函数。

SQL> create or replace package sales_app_pkg is
 2  procedure set_sales_context;
 3  function where_condition
 4  (p_schema_name varchar2,p_tab_name varchar2)
 5   return varchar2;
 6 end;
 7 /
SQL> create or replace package body sales_app_pkg is
 2 procedure set_sales_context is
 3   v_user varchar2(30);
 4 begin
 5  dbms_session.set_context('sales_ctx','seller_id',user);
 6 end;
 7
 8 function where_condition
 9 (p_schema_name varchar2,p_tab_name varchar2) return varchar2 is
 10  v_seller_id varchar2(100) := upper(sys_context('sales_ctx','seller_id'));
 11  v_where_condition varchar2(2000);
 12 begin
 13  if v_seller_id like 'S%' then
 14   v_where_condition := 'seller_id = ' || '''' || v_seller_id || '''';
 15  else
 16   v_where_condition := null;
 17  end if;
 18  return v_where_condition;
 19 end;
 20 end;
 21 / 

在这里,我们主要关注 where_condition 函数,该函数会为 FGAC 规则返回限定条件。这种 FGAC 规则函数必须具有两个传入参数,第一个参数表示 schema 名称,第二个参数表示表的名称。表示对哪 个schema 下的哪个表添加FGAC 规则。同时必须返回字符型的值,该返回值会被Oracle 自动添加到 SQL 语句中的where条件部分。不过函数名称和参数名称可以按照需要进行指定。从这里定义的函数 体中可以看出,如果登录的用户名以S 开头,则会受到FGAC 规则的限制,where 条件里会添加 seller_id='Sxxxx' ,Sxxxx 表示登录的用户名。否则,如果以其他用户的身份登录,则不会受到FGAC规则的限制。

创建了用于FGAC 规则的函数以后,我们开始定义FGAC 规则。

SQL> connect / as sysdba
SQL> begin
 2  dbms_rls.add_policy(
 3    OBJECT_SCHEMA=>'oe',
 4    OBJECT_NAME=>'sales_list',
 5    POLICY_NAME=>'oe_sales_list_fgac',
 6    FUNCTION_SCHEMA=>'oe',
 7    POLICY_FUNCTION=>'sales_app_pkg.where_condition',
 8    STATEMENT_TYPES=>'select,update',
 9    UPDATE_CHECK=>true,
 10    ENABLE=>true);
 11 end;
 12 / 

如上所示,我们使用 dbms_rls 程序包来创建 FGAC 规则。我们为用户 OE下的sales_list 表创建了 规则;该规则利用用户 OE下的sales_app_pkg.where_condition 函数返回 where条件;该规则作用的 SQL 语句类型为select 和update ;update_check 参数说明是否对更新以后的结果判断是否满足 FGAC 规则; 在创建规则的同时,我们也启用该规则(enable 设置为true )。

创建了FGAC 规则以后,我们需要在用户登录到应用程序的时候,调用 sales_app_pkg  程序包里 的set_sales_context 存储过程来设置该用户的应用程序上下文里的 seller_id 属性的值。在实际应用中, 我们可以在登录界面上,当用户单击登录按钮的时候进行设置。在这里为了演示效果,我们创建一个 登录触发器来设置,如下所示:

SQL> connect / as sysdba
SQL> create or replace trigger set_seller_id_on_logon
 2 after logon on DATABASE
 3 begin
 4  oe.sales_app_pkg.set_sales_context;
 5 end;
 6 /  

现在,我们可以开始测试FGAC 规则的效果了。

SQL> connect oe/oe
SQL> select seller_id,count(*) from sales_list group by seller_id;
SELLER_ID  COUNT(*)
---------  ---------
S0010        1067
S0030        968
S0020        1465 

以用户OE的身份登录以后,可以看到,三个销售人员各自的数据行数。然后以S0010 的身份登录:

SQL> connect s0010/s0010
SQL> select sys_context('sales_ctx','seller_id') from dual;
SYS_CONTEXT('SALES_CTX','SELLER_ID')
---------------------------------------
S0010
SQL> select seller_id,count(*) from oe.sales_list group by seller_id;
SELLER_ID  COUNT(*)
---------  ---------
S0010        1067 

很明显看到,我们设置的FGAC 规则生效了。我们继续测试更新操作:

SQL> select seller_id,qty_sold from oe.sales_list where id=300;
SELLER_ID  QTY_SOLD
---------  --------
S0010     1
SQL> update oe.sales_list set seller_id='S0020' where id=300;
update oe.sales_list set seller_id='S0020' where id=300
     *
ERROR at line 1:
ORA-28115: policy with check option violation 

由于我们在创建FGAC 规则时,指定了update_check 为true ,当用户 S0010 登录以后更新sales_list 表,将 seller_id 从S0010 更新为S0020 时报错,因为 S0010 无权查询和修改不属于他的销售数据。如 果指定update_check 为false ,则允许这样的update 语句成功。

FGAC 规则的使用是非常灵活的,其关键就在于 where_condition 函数的写法。如果要删除 FGAC规则,则执行下面的代码:

SQL> begin
 2  dbms_rls.drop_policy(
 3    OBJECT_SCHEMA=>'oe',
 4    OBJECT_NAME=>'sales_list',
 5    POLICY_NAME=>'oe_sales_list_fgac');
 6 end;
 7 / 

二、基于列的VPD 

对于某些敏感列来说,比如员工的工资等,我们可以通过创建基于列的 VPD ,从而屏蔽这些敏感列,只有具有权限的用户才能访问这些列。

基于列的VPD 与前面讨论的FGAC 一样,也是通过设置政策来实现的。设置基于列的VPD 时,我们首先需要创建一个政策所需要用到的函数,如下所示。

SQL> connect hr/hr
SQL> create or replace function hr_col_vpd
 2 (p_owner in varchar2,p_obj in varchar2)
 3  return varchar2
 4 is
 5 l_ret  varchar2(2000);
 6 begin
 7   if (p_owner = USER) then
 8    l_ret := NULL;
 9   else
 10    l_ret := '1=2';
 11   end if;
 12   return l_ret;
 13 end;
 14 / 

这里,我们创建了一个规则函数。与 FGAC 规则一样,该函数必须有两个传入参数,第一个表示 要限定的表所属的schema 名称,第二个表示要限定的表的名称。在该函数中,我们定义,如果登录用 户为表的属主,则可以查看所有列;否则,登录用户不是表所属的用户,则不能查看指定列。

至于具体哪些列要被屏蔽,则需要在定义政策时进行指定,如下所示:

SQL> begin
 2 dbms_rls.add_policy(object_schema=>'hr',
 3 object_name=>'employees',
 4 policy_name=>'hr_emp_col_policy',
 5 function_schema=>'hr',
 6 policy_function=>'hr_col_vpd',
 7 statement_types=>'select',
 8 sec_relevant_cols=>'salary',
 9 sec_relevant_cols_opt => dbms_rls.all_rows
 10 );
 11 end;
 12 / 

创建基于列VPD 与创建FGAC 政策一样,也是使用dbms_rls 程序包里的add_policy 存储过程。 在这里,我们定义了一个名为 hr_emp_col_policy 的政策。该政策作用在用户 HR下的employees 表上; 采用的政策函数为用户HR下的hr_col_vpd 。
与FGAC 政策不同的是,我们需要指定另外两个参数:sec_relevant_cols表示要屏蔽的列的名称, 可以指定多个列,列与列之间用逗号隔开;sec_relevant_cols_opt 设置为all_rows,则说明对 employees 表里所有的记录都屏蔽salary 列。

我们以用户HR的身份登录,并显示salary 列。

SQL> connect hr/hr
SQL> select employee_id,last_name,salary from hr.employees where rownum<4;
EMPLOYEE_ID  LAST_NAME      SALARY
-----------  -------------    -------
198        OConnell        2600
199        Grant          2600
200        Whalen         4400 

可以看到所有的salary 列都显示出来了。然后以用户OE的身份登录,执行下面的SQL 语句:

SQL> connect oe/oe
SQL> select employee_id,last_name,salary from hr.employees where rownum<4;
EMPLOYEE_ID  LAST_NAME      SALARY
-----------  -------------    -------
198        OConnell
199        Grant
200        Whalen 

很明显,对于用户OE来说,salary 列已经被屏蔽了。

总结

以上就是本文关于oracle 虚拟专用数据库详细介绍的全部内容,感兴趣的朋友可以浏览本站其他相关专题,有什么问题可以随时留言,小编会及时回复大家。感谢朋友们对本站的支持!

(0)

相关推荐

  • Oracle分页查询性能优化代码详解

    对于数据库中表的数据的 Web 显示,如果没有展示顺序的需要,而且因为满足条件的记录如此之多,就不得不对数据进行分页处理.常常用户并不是对所有数据都感兴趣的,或者大部分情况下,他们只看前几页. 通常有以下两种分页技术可供选择. Select * from ( Select rownum rn,t.* from table t) Where rn>&minnum and rn<=&maxnum 或者 Select * from ( Select rownum rn,t.* fro

  • oracle求和代码示例

    有一张工资表SALARY如下, (NO 员工编号 ,MONEY 工资) NO    NAME     ITEM       MONEY 001    张三        工资        80 001    张三        补贴        86 001    张三        奖金        75 002    李四        工资        78 002    李四        补贴        85 002    李四        奖金        78 求每

  • Oracle RMAN自动备份控制文件方法介绍

    RMAN(Recovery Manager)是一种用于备份(backup).还原(restore)和恢复(recover) 数据库的 Oracle 工具.RMAN只能用于ORACLE8或更高的版本中.它能够备份整个数据库或数据库部件,如表空间.数据文件.控制文件.归档文件以及Spfile参数文件.RMAN也允许您进行增量数据块级别的备份,增量RMAN备份是时间和空间有效的,因为他们只备份自上次备份以来有变化的那些数据块.而且,通过RMAN提供的接口,第三方的备份与恢复软件如veritas将提供更

  • Oracle安装监听器错误的解决方法

    小白在搭载环境时,经常遇到的一个问题就是数据库安装错误,其中Oracle监听器的错误是经常出现的一个错误,搞不好还要重装系统.下面我就总结一下解决监听器配置问题的三个方法. 一.删除监听器重新配置 在cmd命令栏,sercices.msc查看服务,找到Oracle监听器,停止运行.找到配置和移植工具下的Net Configuration Assistant进行简单的删除再重新建一个即可,直接点击下一步(ps重新配置完成后需重启电脑). 二.重新配置IP地址 如果在服务中Oracle监听器已经打开

  • oracle 数据库启动阶段分析

    Oracle Server主要由两部分组成:Instance 和Database .Instance 是指一组后台进程/线程和一块共享内存区域,而 Database是指存储在磁盘上的一组物理文件.本文由数据库 如何启动入手. 数据库的启动 首先来分析一下数据库的启动过程,Oracle 数据库的启动主要包含 3 个步骤: (1)启动数据库到 nomount 状态: (2)启动数据库到 mount 状态: (3)启动数据库到 open 状态. 下面逐个来看看各个步骤的具体过程以其含义. 1. 启动数

  • oracle 虚拟专用数据库详细介绍

    所谓虚拟专用数据库(VPD)指的是,通过在数据库里进行配置,从而让不同的用户只能查看某个表里的部分数据.VPD分为以下两个级别. 行级别:在该级别下,可以控制某些用户只能查看到某些数据行.比如,对于销售数据表sales 来说,每个销售人员只能检索出他自己的销售数据,不能查询其他销售人员的销售数据. 列级别:在该级别下,可以控制某些用户不能检索某个表的某个列的值.比如用户HR 下的 employees 表中,含有工资(salary)列,由于该列比较敏感,因此不让其他用户查询该列的值. 其他用户检索

  • powershell玩转sqlite数据库详细介绍

    脚本经常需要处理文本,有时候是行列整齐文本.那么powershell脚本处理行列文本有几种方法呢?一种是excel,另外的一些是?access?sqlite? sqlite是一个很小巧的,很方便嵌入到脚本语言中的,关系型数据库.它给powershell提供了一个免费的,处理行列整齐数据,存储数据,统计数据的极品神器. 只要你学会了它,上天入地皆可去得.而且以后学sql server,mysql,都类似,没有难度. 带着引号搜本文关键字: "^_^上天入地皆可去^_^" 发文初衷:世界上

  • System.Data.SQLite 数据库详细介绍

    SQLite介绍在介绍System.Data.SQLite之前需要介绍一下SQLite,SQLite是一个类似于Access的单机版数据库管理系统,它将所有数据库的定义(包括定义.表.索引和数据本身)都保存在一个单一的文件中.并且,SQLite是一个用C实现的类库,它在内存消耗.文件体积.简单性方面都有不错的表现,如果数据在10W条以下,查询速度也是相当快的.SQLite具有以下特征:实现多数SQL92的标准,包括事务(原子性.一致性.隔离性和持久性).触发器和大多数的复杂查询.不对插入或者更新

  • Oracle中转义字符的详细介绍

    最近工作中遇到一个需求,需要更新Oracle数据库中所有表的一个字段"flag"为"I",语句为: update table_name set flag = 'I' "I"作为字符串,所以语句中I需要加上单引号. 由于数据库中有多张表,我不想一条一条的语句写,希望能够通过sql语句直接生成所有的语句,所以写了如下sql: select 'update ' || table_name || ' set flag = 'I'' || ';' from

  • Oracle 闪回技术详细介绍及总结

    Oracle闪回技术详解,这里整理了4种闪回技术,对Oracle 闪回技术做一个整理总结.  概述: 闪回技术是Oracle强大数据库备份恢复机制的一部分,在数据库发生逻辑错误的时候,闪回技术能提供快速且最小损失的恢复(多数闪回功能都能在数据库联机状态下完成).需要注意的是,闪回技术旨在快速恢复逻辑错误,对于物理损坏或是介质丢失的错误,闪回技术就回天乏术了,还是得借助于Oracle一些高级的备份恢复工具如RAMN去完成(这才是Oracle强大备份恢复机制的精髓所在啊)  撤销段(UNDO SEG

  • oracle 创建表空间详细介绍

    注意点: 1.如果在PL/SQL 等工具里打开的话,直接修改下面的代码中[斜体加粗部分]执行 2.确保路径存在,比如[D:\oracle\oradata\Oracle9i\]也就是你要保存文件的路径存在 /*分为四步 */ /*第1步:创建临时表空间 */ 复制代码 代码如下: create temporary tablespace user_temp tempfile 'D:\oracle\oradata\Oracle9i\user_temp.dbf' size 50m autoextend

  • python中使用mysql数据库详细介绍

    一.安装mysql 如果是windows 用户,mysql 的安装非常简单,直接下载安装文件,双击安装文件一步一步进行操作即可. Linux 下的安装可能会更加简单,除了下载安装包进行安装外,一般的linux 仓库中都会有mysql ,我们只需要通过一个命令就可以下载安装: Ubuntu\deepin 复制代码 代码如下: >>sudo apt-get install mysql-server >>Sudo apt-get install  mysql-client centOS/

  • oracle数据库关于索引建立及使用的详细介绍

    索引的说明 索引是与表相关的一个可选结构,在逻辑上和物理上都独立于表的数据,索引能优化查询,不能优化DML操作,Oracle自动维护索引,频繁的DML操作反而会引起大量的索引维护. 如果SQL语句仅访问被索引的列,那么数据库只需从索引中读取数据,而不用读取表. 如果该语句同时还要访问除索引列之外的列,那么,数据库会使用rowid来查找表中的行. 通常,为检索表数据,数据库以交替方式先读取索引块,然后读取相应的表块. 索引的目的 主要是减少IO,这是本质,这样才能体现索引的效率. 1大表,返回的行

  • 达梦数据库获取SQL实际执行计划方法详细介绍

    目录 一.set autotrace trace 二.v$cachepln中获取执行计划 三.ET系统函数 四.dbms_sqltune系统包 五.说明 环境说明: 操作系统:银河麒麟V10 数据库:DM8 相关关键字:DM数据库.SQL实际执行计划 一.set autotrace trace disql下执行set autotrace trace开启AUTOTRACE功能,执行SQL语句,并打印实际的执行计划. SQL> set autotrace trace SQL> select a.e

  • Oracle 11g数据库详细安装图文教程

    本教程为大家分享了Oracle 11g数据库详细安装步骤,供大家参考,具体内容如下 1.先到Oracle官网上下载11g oracle Database 11g第 2 版 (11.2.0.1.0) 标准版.标准版 1 以及企业版 适用于 Microsoft Windows (x64) 的 Oracle Database 11g第 2 版 (11.2.0.1.0) 第一步:将两个文件一起解压到同一目录下的同一文件夹内, 路径名称中不要出现中文,也不要出现空格等不规则字符. 解压完成后,到相应路径下

随机推荐