· 作者 小荷||【转载时请务必以超链接形式标明文章原始出处和作者信息】
· 永久链接: http://www.oracleblog.org/working-case/exclude-some-table-in-9i-exp/


在做exp的时候,我们可以做owner级的导出,导出该用户下的所有对象。owner级的导出,会导出所有的表,不太容易排除单独的一些表;而如果做table级的导出,就必须列出所有的table,且当数据库有增加新table的时候,也得把新增的table加到exp的列表中。

今天收到一个客户的要求,做owner级别的导出,但是需要排除几张大表。该需要做成定时的脚本每天执行。

其实,如果在10g中用数据泵,这个exclude很方便处理,但是在9i中,用什么方法才能把某些表单独排除呢?原来我们可以用FGAC来实现。

一、在这里,我们假设我们需要对用户mytest做owner级导出。

SQL> create user mytest identified by mytest default tablespace users;
 
用户已创建。
 
SQL> grant connect,resource to mytest;
 
授权成功。
 
SQL>
SQL> conn mytest/mytest
已连接。
SQL>
SQL>
SQL> create table t1 as select * from dual;
 
表已创建。
 
SQL>
SQL>
SQL> create table t2 as select * from all_objects;
 
表已创建。
 
SQL> select table_name from user_tables;
 
TABLE_NAME
------------------------------
T1
T2
 
SQL>

二、新建一个用户用于做exp的导出,新建该用户的目的是:该用户只是用来做exp导出,而不修改原来的dba用户或者application用户来做exp导出:

SQL> create user expuser identified by expuser default tablespace users;
 
用户已创建。
 
SQL> grant connect,resource,dba to expuser;
 
授权成功。
 
SQL>

三、建立exclude_table 函数:

SQL> conn expuser/expuser
已连接。
SQL> CREATE or REPLACE FUNCTION exclude_table(obj_schema VARCHAR2,
  2                                           obj_name   VARCHAR2)
  3    RETURN VARCHAR2 IS
  4    d_predicate VARCHAR2(2000);
  5  BEGIN
  6    if sys_context('USERENV', 'SESSION_USER') = 'EXPUSER' THEN
  7      d_predicate := '1=2';
  8    else
  9      d_predicate := '';
 10    end if;
 11    RETURN d_predicate;
 12  END exclude_table;
 13  /
 
函数已创建。
 
SQL>

这个函数用来控制用户对某个表的访问,FGAC大致的功能是利用dbsm_rls部署一些策略(policy),这些策略会调用一些函数,比如上面我定义的那个exclude_table函数,利用函数,来使得普通执行的sql后面加上谓词。

比如,某sql是:

select table_name from dba_tables;

被细粒度权限控制之后,这个sql语句会自动在后面加上where的谓词做过滤,变成类似:

select table_name from dba_tables where owner='MYUSER';

因此,当被细粒度权限控制之后,就算执行select table_name from dba_tables;也只能出现owner=’MYUSER’的表。

回到上面的exclude_table函数,大致的意思就是当操作的用户是EXPUSER的时候,就在操作的语句后面加1=2,我们知道1=2为非真,因此能select出来的结果肯定是0行。因此,这样就类似的实现了我们对某些表做exp的时候,不导出数据的目的。

好,我们继续把这个函数的功能加到mytest用户下的t1表上。我们用dbms_rls.add_policy来实现,我们先看一下这个过程的参数:

PROCEDURE ADD_POLICY
参数名称                       类型                    输入/输出默认值?
------------------------------ ----------------------- ------ --------
 OBJECT_SCHEMA                  VARCHAR2                IN     DEFAULT
 OBJECT_NAME                    VARCHAR2                IN
 POLICY_NAME                    VARCHAR2                IN
 FUNCTION_SCHEMA                VARCHAR2                IN     DEFAULT
 POLICY_FUNCTION                VARCHAR2                IN
 STATEMENT_TYPES                VARCHAR2                IN     DEFAULT
 UPDATE_CHECK                   BOOLEAN                 IN     DEFAULT
 ENABLE                         BOOLEAN                 IN     DEFAULT
 STATIC_POLICY                  BOOLEAN                 IN     DEFAULT
 POLICY_TYPE                    BINARY_INTEGER          IN     DEFAULT
 LONG_PREDICATE                 BOOLEAN                 IN     DEFAULT
 SEC_RELEVANT_COLS              VARCHAR2                IN     DEFAULT
 SEC_RELEVANT_COLS_OPT          BINARY_INTEGER          IN     DEFAULT
 
几个主要字段的解释:
object_schema:用来做细粒度访问控制对象所对应的用户,如果为空则默认是当前用户。
object_name:用来做细粒度访问控制对象(可以是表,或视图或同义词)
policy_name:策略名,可自定义。但是如果对同一表或者视图,策略名必须唯一。但是如果是不同用户下的同一个表或者视图,可以用相同的策略名。
function_schema:自定义函数的用户,该用户应该有权限能调用之前我们建立的那个函数。如果为空,则默认是当前用户。
policy_function:函数名,即之前我们自己定义谓词的函数,如果函数定义在包里面,则这里也需写上包的名字。
statement_types:操作的类型,如select,insert,update或delete,如果为空,则默认是所有类型的操作。

因此对于排除mytest用户下的t1表,我们可以执行:

SQL> exec dbms_rls.add_policy(OBJECT_SCHEMA=>'MYTEST',OBJECT_NAME=>'T1',POLICY_NAME=>'POL_T1',FUNCTION_SCHEMA=>'EXPUSER'
,POLICY_FUNCTION=>'EXCLUDE_TABLE');
 
PL/SQL 过程已成功完成。
 
SQL>

上述的结果可以用这个sql去检查:

SQL> select OBJECT_OWNER,OBJECT_NAME,POLICY_GROUP,POLICY_NAME,PF_OWNER,FUNCTION from dba_policies
  2  where PF_OWNER='EXPUSER';
 
OBJECT_OWN OBJECT_NAM POLICY_GROUP                   POLICY_NAM PF_OWNER   FUNCTION
---------- ---------- ------------------------------ ---------- ---------- ------------------------------
MYTEST     T1         SYS_DEFAULT                    POL_T1     EXPUSER    EXCLUDE_TABLE
 
SQL>

四、好,我们现在来测试owner级导出:
1、我们先测试一下select操作:

SQL> conn system/manager
已连接。
SQL> select * from mytest.t1;
 
D
-
X
 
SQL>
SQL> conn expuser/expuser
已连接。
SQL> select * from mytest.t1;
 
未选定行
 
SQL>

这里的区别已经很明显的看出来了。

2、最后我们来实现我们的需求,按照owner级的导出,却排除t1表:

C:\>exp expuser/expuser owner=mytest file=mytest.dmp log=mytest.log;
 
Export: Release 10.2.0.1.0 - Production on 星期五 1月 7 22:25:34 2011
 
Copyright (c) 1982, 2005, Oracle.  All rights reserved.
 
 
连接到: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
已导出 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集
 
即将导出指定的用户...
. 正在导出 pre-schema 过程对象和操作
. 正在导出用户 MYTEST 的外部函数库名
. 导出 PUBLIC 类型同义词
. 正在导出专用类型同义词
. 正在导出用户 MYTEST 的对象类型定义
即将导出 MYTEST 的对象...
. 正在导出数据库链接
. 正在导出序号
. 正在导出簇定义
. 即将导出 MYTEST 的表通过常规路径...
EXP-00079: 表 "T1" 中的数据是被保护的。常规路径只能导出部分表。
. . 正在导出表                              T1导出了           0 行
EXP-00091: 正在导出有问题的统计信息。
. . 正在导出表                              T2导出了       38250 行
. 正在导出同义词
. 正在导出视图
. 正在导出存储过程
. 正在导出运算符
. 正在导出引用完整性约束条件
. 正在导出触发器
. 正在导出索引类型
. 正在导出位图, 功能性索引和可扩展索引
. 正在导出后期表活动
. 正在导出实体化视图
. 正在导出快照日志
. 正在导出作业队列
. 正在导出刷新组和子组
. 正在导出维
. 正在导出 post-schema 过程对象和操作
. 正在导出统计信息
导出成功终止, 但出现警告。
 
C:\>

我们看到t1表导出了0行(但是表结构还是被导出的)。

五、取消FGAC。
取消很容易,执行执行dbms_rls中的drop_policy即可:

SQL> exec dbms_rls.drop_policy(OBJECT_SCHEMA=>'MYTEST',OBJECT_NAME=>'T1',POLICY_NAME=>'POL_T1');
 
PL/SQL 过程已成功完成。
 
SQL>


转载于:https://www.cnblogs.com/nclly/archive/2011/10/25/2223633.html

在9i的数据库中排除某些表做owner级导出相关推荐

  1. Oracle表里的照片怎么导出来,如何导出oracle数据库中某张表到excel_oracle数据库表格导出到excel...

    如何将oracle数据库表字段导成excel表格 这个你只要用ADO连oracle并获取记录集,根据你用的编程语言打开EXCEL,然后操作EXCEL对象的工作表就可以了.以VB为例: 1.在工程中引用 ...

  2. SQL - 通过某个字段名称找到数据库中对应的表

    工作中,我们经常会碰到会为一个已有的系统增加一些东西,如在报表中增加一些字段,或者在导出Excel文件时增加一些Column. 这时侯,我们不知道我们需要的数据在数据库中的哪个表中.至少,我们知道这个 ...

  3. SQL Server 将指定的数据库中的所有表都列出来

    在很多情况下我们需要将指定的数据库中的所有表都列出来.在使用c#进行软件开发时,我们有哪些方法可是实现这个目的呢?本人对此进行概要的总结,有以下6中方式可以实现这个目的. 1.sqldmo SQLDM ...

  4. mysql select 所有表_怎样用SQL语句查询一个数据库中的所有表

    展开全部 查询32313133353236313431303231363533e59b9ee7ad9431333431356639一个数据库中的所有表sql语句是show tables: 显示所有数据 ...

  5. 获取数据库中的所有表

    本Blog登出后受到了大家的关注,其中"盛国军"朋友提出了使用存储过程"sp_tables"也可以实现这个目的,所有本人对这个Blog有进行了完善. 在很多情况 ...

  6. Java代码判断数据库中某张表是否存在

    最近在开发一个同步数据的统计任务的时候遇到一个问题:要在Java代码中判断数据库中某张表是否存在,查资料后,总结了以下两种方法: 1.使用JdbcTemplate bean public boolea ...

  7. 一条SQL语句查询数据库中的所有表、存储过程、触发器

    一条SQL语句查询数据库中的所有表.存储过程.触发器 (sysobjects表信息)   该条语句查询返回所有的用户表 select * from sysobjects where xtype='u' ...

  8. SQLSERVER如何获取一个数据库中的所有表的名称、一个表中所有字段的名称

    1.查询数据库中的所有数据库名: 1 SELECT Name FROM Master..SysDatabases ORDER BY Name 2.查询某个数据库中所有的表名: 1 SELECT Nam ...

  9. SQL2000数据库中删除“坏表”的方法

    SQL2000数据库中删除"坏表"的方法 在一些网站或者软件系统中,由于安全或者程序异常等问题,可能会在SQL Server 2000中造成一个异常问题:在企业管理器中打开数据库发 ...

  10. mysql中删除数据库中的表格数据恢复_恢复从数据库中删除的表

    恢复从数据库中删除的表Recover tables deleted from a database 09/25/2018 本文内容 本主题演示如何创建一个示例 Visual Basic for App ...

最新文章

  1. 文巾解题 50. Pow(x, n)
  2. 太原理工软件学院c语言2020,太原理工软件工程C语言实验报告 数组.doc
  3. 一个迄今为止最快的并发键值存储库FASTER诞生
  4. 和哪个专业的男生谈恋爱最惨?
  5. 2019 ICPC World Finals Problem J. Miniature Golf
  6. html JSP 富文本案例,JSP页面引入Ueditor富文本编辑器!
  7. C++/C学习笔记(九)
  8. Class类的创建方式大全
  9. 并发编程模型Akka
  10. python定义一维数组
  11. Atitit.数据库存储引擎的原理与attilax 总结
  12. 身份证阅读器读卡器React网页方法实现身份证的读取
  13. 【Scratch案例实操】scratch变魔术 scratch编程案例教学 scratch创意编程 少儿编程教案
  14. gliffy UML破解工具
  15. 新基建安全怎么做?看看这场院士领衔的高峰对话
  16. 计算机基础常用英语,计算机常用基础英语
  17. 我们都有过一段很美好的时光
  18. 学java用什么写比较好_学习Java需要什么基础,初学Java如何写好代码
  19. 计算机网络之应用层(DNS域名系统)
  20. 这个七夕,送你一份程序员教科书级别的告白指南

热门文章

  1. Access优已成忧,一年后,还是离开了秋色园了
  2. SQL Server 2008数据库快照技术(八)
  3. 同事乱用分页 MySQL 卡爆,我真是醉了...
  4. 阿里P8架构师:淘宝技术架构从1.0到4.0的架构变迁!12页PPT详解
  5. 我的天!你竟然不会用IDEA远程调试Tomcat...
  6. 同事线上埋的这个坑,我整整找了3天3夜
  7. GitHub 热榜:文字识别神器,超轻量级中文 OCR!一个超级厉害的开源库
  8. 中国 X86 服务器市场 10 年来首次负增长
  9. IT人是这么过圣诞的……
  10. 2 imwrite中文路径_如何为FreePBX/Asterisk配置中文语音支持