RSS订阅
RSS订阅TT数据库

将数据行内容的变化记入日志(第一部分)

2008-7-17  选择字号:  | |
打印本文章

导读:将数据行内容的变化记入日志理想的解决方案就是将新旧值都发送给一个SP,然后SP通过对名字、原来的值、新的值进行比较,并创建一条日志记录。但是,新旧值不能够……

关键词:数据行 内容 变化 写入日志 日志 Oracle PL/SQL

正在加载数据... 【TechTarget中国原创】我想要使用一些写日志的功能性。主要的问题就是,有大量的表中的数据行的内容发生了改变,需要将这些变化记录日志。针对每个数据行,我都需要比较原来的值和新的值,然后只记录下变化的。我不想为每个表中的特定的列名字写一个触发器,这要是维护起来简直就是噩梦(除非我可以使用一些类似AFTER create OR alter ON触发器的东西来重新写入日志触发器?)。理想的解决方案是将新旧值都发送给一个SP,然后SP通过对名字、原来的值、新的值进行比较,并创建一条日志记录。但是,据我所知,新旧值不能够作为一种数组来处理。看起来惟一的办法就是使用如下的语法:old.colname了。您有什么看法吗?

【TechTarget中国原创】问:我想要使用一些写日志的功能性。主要的问题就是,有大量的表中的数据行的内容发生了改变,需要将这些变化记录日志。针对每个数据行,我都需要比较原来的值和新的值,然后只记录下变化的。我不想为每个表中的特定的列名字写一个触发器,这要是维护起来简直就是噩梦(除非我可以使用一些类似AFTER create OR alter ON触发器的东西来重新写入日志触发器?)。理想的解决方案是将新旧值都发送给一个SP,然后SP通过对名字、原来的值、新的值进行比较,并创建一条日志记录。但是,据我所知,新旧值不能够作为一种数组来处理。看起来惟一的办法就是使用如下的语法:old.colname了。您有什么看法吗?

  回答:你可以创建一个名字为DATA_CHANGE_AUDIT 的表,表的结构如下,可以存储数据库中所有表的数据变化:

  create TABLE DATA_CHANGE_AUDIT
  (TABLE_NAME         VARchar2(30),
  PRIMARY_KEY_VALUE  VARchar2(100),
  COLUMN_NAME        VARchar2(30),
  ACTION_DATE        DATE,
  OLD_VALUE          VARchar2(4000),
  NEW_VALUE          VARchar2(4000),
  USER_NAME          VARchar2(30))

  现在,你可以创建一些函数和过程,来动态生成你的计划中所有表的所有日志触发器。执行这些过程的时候,一定要将serveroutput设置为‘on’。

create OR REPLACE FUNCTION GENERATE_TRIG_NAME(p_Table_name IN VARchar2) RETURN VARchar2 IS
BEGIN
    RETURN SUBSTR(’TRIG_’|| p_Table_name,1, 30); 

  --你应该注意使这个函数生成的名字是惟一的。
 

END GENERATE_TRIG_NAME;
/
create OR REPLACE PROCEDURE create_AUDIT_TRIG_DYNAMIC(p_Table_Name IN VARchar2) IS
   CURSOR C1 (p_Table IN VARchar2) IS
       select t1.COLUMN_NAME, t3.DATA_TYPE, t1.POSITION, T4.LAST_POSITION
         FROM
          USER_CONS_COLUMNS t1,
          USER_CONSTRAINTS t2,
          USER_TAB_COLUMNS t3,
         (select t6.TABLE_NAME, MAX(t5.POSITION) LAST_POSITION
         FROM USER_CONS_COLUMNS t5,
              USER_CONSTRAINTS t6
        where
              t6.TABLE_NAME   = p_Table
          AND t5.CONSTRAINT_NAME  = t6.CONSTRAINT_NAME
          AND t6.CONSTRAINT_TYPE  = ’P’
          GROUP BY t6.TABLE_NAME ) t4
     where
         t2.TABLE_NAME       = p_Table
     AND t2.TABLE_NAME       = t4.TABLE_NAME
     AND t1.CONSTRAINT_NAME  = t2.CONSTRAINT_NAME
     AND t2.CONSTRAINT_TYPE  = ’P’
     AND t1.TABLE_NAME       = t3.TABLE_NAME
     AND t1.COLUMN_NAME      = t3.COLUMN_NAME
     ORDER BY t1.POSITION;
   CURSOR c2(p_Table IN VARchar2) IS
     select COLUMN_NAME, COLUMN_ID
       FROM
         USER_TAB_COLUMNS
       where
          TABLE_NAME   = p_Table
       ORDER BY COLUMN_ID;

  --在 Cursor C2 中,如果你有类似Modified by, 或者 created by,或者创建日期的列,你需要通过如下的各项来排除那些列:AND COLUMN_NAME NOT IN ’MODIFIED_BY’,’DATE_MODIFIED’,’createD_BY’,’DATE_createD’).
  
  --在针对这些列插入或者更新之前,你必须要在表上用另一个审计触发器。

  未完待续,参见第2部分。


将数据行内容的变化记入日志
 将数据行内容的变化记入日志(第一部分)
 将数据行内容的变化记入日志(第二部分)

还没有登录? 阅读全文请先登录或注册
用户名:(请填写您的E-mail做为登录账号)
  • 获取最新的IT业界资讯、市场动态、行业趋势等独家原创内容。
  • 分享国内外技术专业人士提供的技巧经验。
  • 利用专注IT的技术资源中心,不断更新专业知识。
  • 享受白皮书、Webcast等系列特色增值服务。
  • 免费参加TT中国举办的各种会员活动。
  • 更多的精彩服务,在不断开发中……
用户名:(请填写您的E-mail)
密 码:
 永久登录
请输入您的登录email:
相关的新闻
本文主要介绍Oracle Developer 2000中的一些实用语句,如go_block(name); 定位到指定的块、go_item(name); 定位到指定的项、go_form(name); 定位到……
Oracle Developer 2000中有哪些实用语句?本文主要介绍Oracle Developer 2000中的实用语句,如abort_query; 停止查询的执行等等。
当以其中的一个表有两个外键指向另一个表的主键时,我们怎样从两个表中检索数据?例如,表A有两个列,Parent_ID和Child_ID。表B有两个列,ID和名字。我们怎样检索数据并……
Oracle11g的数据泵新增了一个DATA_OPTIONS选项,目前只有一个参数SKIP_CONSTRAINT_ERRORS。利用这个参数可以在导入数据的时候,忽略掉违反约束的数据,使得其他正常……
Oracle 11g的STANDBY数据库可以在应用日志的同时打开数据库,但是对于RAC环境,这里还是有一些小的问题。即使是RAC环境,STANDBY数据库也只能有一个实例在进行……

本专题介绍了SQL Server服务代理相关方面的知识,包括SQL Server服务代理基础知识的概述、消息类型、契约、队列、服务和路由、SEND命令和RECEIVE命令、性能方面的改进以及对运行状况的监控等等。

无论你是否计划将SQL Server数据库转换服务(DTS)包迁移到SQL Server集成服务(SSIS)或在SQL Server 2005里运行DTS包,都需要专家的一些建议。这一指南主要是包括SSIS的相关基础知识、技巧帮助你进行SSIS调整,还介绍了SSIS有经验的一些用户的具体信息等等。

子查询是一个嵌套在SELECT、INSERT、UPDATE 或DELETE语句,或者另一个子查询里的查询。一个子查询可以返回一行或多行结果给父查询。标量子查询是只返回一个值的查询:只有一个字段的一行记录。标量子查询可以在SQL语句的大多数位置,其中你可以使用一个表达式或一个实际值。
最新更新
专家答疑
技巧
Michael Hillenbrand
你能解释一下数据库公程师、数据库架构师以及数据库管理员之间有什么区别吗?数据库管理员:这是目前最普遍使用的对从事数据库相关的工作的人的头衔。数据库管理员是指……
Brian Peasland
对5GB大小的Oracle 7.3存档或删除的最佳办法是什么?为了便于管理机构查询,这些数据至少需要再用20年的时间。我们担心将来我们不能对它重新获取并迁入一个更新的……
Rudy Limeback
如何创建一个约束限制2007年1月1日之前的日期被录入?用CHECK约束就可以。如下面的示例……