2013-03-26 48 views
-1

我对DBA的概念非常陌生。作为工作的一部分,我创建了一个内部数据集市。通过使用数据库链接,我已连接到不同的数据源,并且要求将这些信息存储在此市场中。我们要求通过数据库链接连接的数据源日益变化。所以我们想要跟踪那些数据的变化。所以我创建了一个物化视图,并编写了一个过程在一个月内刷新这些表。意味着主表总是在一个月内刷新一次新数据,我们会将旧数据发送到历史表。在刷新这些表之前,我写了一个简单的逻辑将数据从主表移动到历史表。 例如: 假设员工表作为主表,以保持该表的历史我很书面方式一个简单的声明一样如何保持6个月的历史数据?

create table employee_hst as select * from employee;(带时间戳)

但简单的声明是不是我的服务宗旨。

因为我的要求是我应该只保留6个月的历史。我的意思是历史表应该只保存6个月的历史数据。因此,请告诉我如何在历史数据中仅保存6个月的旧数据,并且超过6个月的数据应自动删除。

请帮助您的建议。

在此先感谢

+0

这听起来像是完美的分区选择。您是否拥有许可的分区选项? – 2013-03-26 19:13:20

回答

0

你可以创建一个存储过程,

  1. 插入到历史
  2. 刷新materilaised查看
  3. 从历史记录中删除where DateCreated < Sysdate - 180
+0

从“插入历史记录”中删除表中的内容将非常不直观。特别是首次运行的表现将是非确定性的。 – 2013-03-26 19:01:33

+0

@ Clockwork-Muse - 我不明白你的意见 – 2013-04-03 16:29:25

+0

想想你的SP会被命名为什么;它是“insertIntoHistory”吗?如果是这样,为什么会删除任何东西?它是否被命名为'insertAndDeleteFromHistory'?如果是这样,这是否意味着刚插入的行也被删除(或与删除的行有关)?实际上,插入行与删除完全不同:由于大小或满足法定要求(或其他),行被删除。 ...另外,在每次插入将成为一个表演猪(和_before_删除?)后,我有一种感觉刷新物化视图。 – 2013-04-03 16:50:46

0

您可以创建雇员表上的触发器将在IN上执行SERT/UPDATE/DELETE,它会做两件事:1)复制历史表中的当前记录。历史表将有一个单独的字段作为varchar [20]或类似的东西,可以容纳“INSERT/UPDATE/DELETE”动作以及时间戳字段。它将执行的第二个操作是删除历史记录表中超过180天的任何记录。

+0

实际上,从“添加到历史记录”触发器中删除历史记录将是非常不直观的。尤其从性能的角度来看。 – 2013-03-26 18:58:42

0

几乎所有的RDBMS都具有某种调度服务,包括Oracle

最好的办法是将预定作业添加到此服务中,该作业将删除6个月以上(或180天或您有什么)的所有历史记录。

1

这是根据scott.emp表格可能需要的简化版本。首先是向您展示查询和输出。你也可以使用间隔或ADD_MONTHS获得的数据在过去的6个月:

SELECT * FROM 
(
SELECT deptno, empno, ename, end_date AS hiredate 
     , TRUNC(MONTHS_BETWEEN(sysdate, end_date)) months_of_service 
    FROM emp_test 
) 
WHERE months_of_service <= 6 -- past 6 moths data only 
ORDER BY 1 
/

DEPTNO EMPNO ENAME  HIREDATE MONTHS_OF_SERVICE 
------------------------------------------------------------ 
10  7782  CLARK  11/2/2012 4 
10  7934  MILLER 9/2/2012  6 
... 
20  7902  FORD  9/2/2012  6 
20  7566  JONES  10/2/2012 5 
... 
30  7935  WALSH  12/2/2012 3 
30  7900  JAMES  9/2/2012  6 
30  7844  TURNER 1/27/2013 1 
... 

下面的例子是基于您的文章 - 你想每次都重新创建表并用数据填充它。您也可以截断表格并重新插入数据 - 取决于您。我个人会选择截断/插入,而不是动态地删除/创建表。

使用表名作为参数创建过程,或者手动运行块,或者使用DBMS_SCHEDULER或其他工具安排每个时间间隔自动运行到SCHEDULER。

在表名称前添加模式名称。如果在运行Drop表部分之前表已存在,则从代码中移除异常部分。如果你得到“ORA-00942:表或视图不存在”,那么你需要一个例外。

DECLARE 
    v_tab_name VARCHAR2(100):= 'emp_test2'; 
BEGIN 
    EXECUTE IMMEDIATE 'DROP TABLE '|| v_tab_name; -- may truncate then insert 
    -- This exception will handle ORA-00942: table or view does not exist 
    -- If table already exists before you run this then you may remove it from code 
    EXCEPTION WHEN OTHERS 
    THEN 
    BEGIN 
     EXECUTE IMMEDIATE 'CREATE TABLE '||v_tab_name||' AS -- or insert into select... 
        SELECT * FROM 
        (
        SELECT deptno, empno, ename, end_date 
         , TRUNC(MONTHS_BETWEEN(sysdate, end_date)) months_of_service 
        FROM emp_test 
        ) 
        WHERE months_of_service <= 6 
        ORDER BY 1'; 

     EXCEPTION WHEN OTHERS THEN dbms_output.put_line(SQLCODE||' '||SQLERRM); 
    END; 
END; 
/