-1

我对 DBA 概念非常陌生。作为工作的一部分,我创建了一个内部数据集市。通过使用数据库链接,我已经连接到不同的来源,并且要求任何数据都将信息存储在这个集市中。我们要求我通过数据库链接连接的数据源每天都在变化。所以我们想跟踪这些数据的变化。所以我创建了一个物化视图并编写了一个程序来每月刷新一次这些表。意味着主表总是每月刷新一次新数据,我们会将旧数据发送到历史表。所以在刷新这些表之前,我编写了一个简单的逻辑来将数据从主表移动到历史表。示例:假设该员工表作为主表,为了维护该表的历史记录,我正在编写一个简单的语句,例如

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

但这个简单的陈述不符合我的目的。

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

请帮助您的建议。

提前致谢

4

4 回答 4

1

这是基于 scott.emp 表的您可能需要的简化版本。首先是向您展示查询和输出。您还可以使用 INTERVAL 或 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 table 部分下运行之前表已经存在,则从代码中删除异常部分。如果你得到“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;
/
于 2013-03-26T19:35:32.220 回答
0

Can you create a trigger on the employee table that will execute on INSERT/UPDATE/DELETE, which would do two things: 1) copy the current record in the history table. The history table would have a separate field as a varchar[20] or something similar that would hold the action "INSERT/UPDATE/DELETE" as well as a timestamp field. The second action that it would do is to delete any records in the history table older than 180 days.

于 2013-03-26T17:47:36.060 回答
0

您可以创建一个存储过程

  1. 插入历史
  2. 刷新物化视图
  3. 从历史中删除where DateCreated < Sysdate - 180
于 2013-03-26T17:42:54.860 回答
0

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

您最好的选择是向此服务添加一个预定的作业,删除所有超过 6 个月(或 180 天或您有什么)的历史记录。

于 2013-03-26T19:04:28.317 回答