【问题标题】:Delete unused records from oracle table从 oracle 表中删除未使用的记录
【发布时间】:2017-11-09 22:09:03
【问题描述】:

数据库版本:11.2.0.4 操作系统 Solaris 5.10

要求:只有在确定记录是否被访问后才从表中删除未使用的记录。

我们有一个表employee,它有100,000 条记录,如果有人从employee 表中选择一个特定的记录/记录,则相应记录的STATUS 列应更新为“ACTIVE”值。

这是审计目的所必需的,60 天后我们将删除员工表中 STATUS 列值为 NULL 的所有记录。如何做到这一点?

目前的理解,如有错误请指正:

1) 触发器不能使用,因为没有 SELECT 事件,我们只有 UPDATE、INSERT、DELETE 事件。 2)Oracle FGA(细粒度审计)可能无法解决目的。或者我可能不知道,FGA 是否可行?

表:

CREATE TABLE EMPLOYEE
(
  EMPID   NUMBER,
  NAME    VARCHAR2(20 BYTE),
  SALARY  NUMBER,
  DEPART  VARCHAR2(100 BYTE),
  STATUS  VARCHAR2(100 BYTE)
)

样本记录:

     EMPID NAME                SALARY DEPART               STATUS    
---------- --------------- ---------- -------------------- ----------
       101 ALFA                  1000 IT                             
       102 BETA                  2000 CLERK                          
       103 PETER                 3000 FINANCE                        
       104 JOHN                  4000 IT                             
       105 MESSI                 5000 TECH                           
       106 ROMEO                 5000 TECH                           
       107 TERI                  5000 TECH                           
       108 ROBERT                5000 TECH                           

例子:

如果有任何以下陈述出现

查询1:SELECT * from EMPLOYEE where name='MESSI';

审核应更新 empid=105 的 STATUS='ACTIVE'

     EMPID NAME                SALARY DEPART               STATUS    
---------- --------------- ---------- -------------------- ----------
       101 ALFA                  1000 IT                             
       102 BETA                  2000 CLERK                          
       103 PETER                 3000 FINANCE                        
       104 JOHN                  4000 IT                             
       105 MESSI                 5000 TECH                 'ACTIVE'                         
       106 ROMEO                 5000 TECH                           
       107 TERI                  5000 TECH                           
       108 ROBERT                5000 TECH                 

查询2:SELECT * from EMPLOYEE where DEPART='TECH';

审核应更新 empid=105,106,107,108 的 STATUS='ACTIVE'

     EMPID NAME                SALARY DEPART               STATUS    
---------- --------------- ---------- -------------------- ----------
       101 ALFA                  1000 IT                             
       102 BETA                  2000 CLERK                          
       103 PETER                 3000 FINANCE                        
       104 JOHN                  4000 IT                             
       105 MESSI                 5000 TECH                 'ACTIVE'                         
       106 ROMEO                 5000 TECH                 'ACTIVE'                                                    
       107 TERI                  5000 TECH                 'ACTIVE'                                                    
       108 ROBERT                5000 TECH                 'ACTIVE'          

【问题讨论】:

  • 如何判断一条记录是否被“读取”?假设我使用一些过滤器进行查询,该查询获得 3 条记录,但 Oracle 对表进行了全面扫描,从而“读取”了所有记录;在这种情况下该怎么办?或者,如果尝试获取 N 记录的查询,然后我在仅获取 1 行的外部查询中使用它;那该怎么办?
  • 您可以使用 FGA 来触发审计,并且在策略创建中,您可以调用您创建的过程。在该过程中,进行所需的更改。

标签: oracle


【解决方案1】:

Oracle 建议的解决方案被称为 ILM 或信息生命周期管理。 它允许您归档、删除、移动或根据某些条件(例如上次访问)执行特定操作。

但请注意,它需要额外的许可证。

我有一个建议:

  1. 对目标表启用 SELECT 审计
  2. 如果 OBJECT_NAME 是您的表,则创建一个 AFTER INSERT TRIGGER 以获取 DBA_AUDIT_TRAIL 中插入的行并提取 SQL_TEXT(+其他检查)
  3. 在此触发器内,执行一些字符串操作以获取 WHERE CONDITION 并将其用于更新。

【讨论】:

    【解决方案2】:

    对我来说,这听起来像是一个模棱两可的要求。如果选择 * 或选择 count(*) 会发生什么?根据规范,将使用所有员工记录。 视图 v$SQL 将包含发出的“所有” SQL 语句,您总是可以在那里查看(通过 v$plan_table 和对象)。如果记录被触及,则使用它们进行逆向工程。

    【讨论】:

      【解决方案3】:

      您可以使用 DBMS_FGA 包尝试 FGA(细粒度审计)。尝试在您的架构中运行下面的代码块。如果成功执行,请在运行选择查询时检查是否定期在 DBA_COMMON_AUDIT_TRAIL 或 DBA_AUDIT_STATEMENT 表中提交审计(检查文档)。安排一个定期运行的程序来检查审计表并相应地更新状态列。但是,我从来没有尝试过这样的事情!。

      BEGIN
                         dbms_fga.Add_policy(object_schema => 'HR', object_name => 'EMPLOYEE',
                         policy_name => 'STATUS_UPDATE', audit_condition => 'SELECT',
                         audit_column => 'NAME ,DEPART', handler_schema => NULL,
                         handler_module => NULL,
                         ENABLE => TRUE);
                     END;
      
                     / 
      

      【讨论】:

        猜你喜欢
        • 2019-11-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多