用触发器生成数据库表的数据操作日志

作为一名数据库管理员,你尽力以各部门熟知的不同格式,向各部门提供它们所需要的数据。你通常将MS Excel格式的数据递交到会计部门,或将数据以HTML报表的形式呈现给普通用户。你们的系统安全管理员们则习惯于用文本阅读器或者事件查看器来查看日志。本文将介绍如何使用触发器,把DML(数据操作语言)对数据库中的特定数据表的改动记录下来。注:下列例子为Insert型触发器,不过改成Delete/Update型的触发器也很容易。

  操作步骤首先让我们在Northwind数据库内创建一个简单表。

create table tablefortrigger
(
 track int identity(1,1) primary key,
 Lastname varchar(25),
 Firstname varchar(25)
)

  创建好这个数据表后,添加一个标准message到master数据库的sysmessages数据表中。注意,我所添加的是一个参变量,用以接受一个字符值,它将被输出显示给管理员们。通过设置@_with_log参数为true,我们包管相关结果被发送到事件日志。

sp_addmessage 50005, 10, '%s', @with_log = true

  现在我们创建这条用有意义的信息填充的消息。下面的信息将填充这条消息,并且记录到文件中:

  ·操作的类型(插入)。

  ·受到影响的数据表。

  ·改动的日期与时间。

  被该语句插入的全部字段。 下面的这个触发器用预定义值(1~3个字符)创建一个字符串,该预定义值位于inserted数据表中。(这个inserted数据表驻留在内存中,它容纳被插入到触发器所在数据表的记录行)。触发器连接这些值并放到一个@msg变量。然后这个变量被传送到raiserror函数,该函数将它写到事件日志中。

Create trigger TestTrigger on
tablefortrigger
for insert
as
--声明储存消息的变量
Declare @Msg varchar(8000)
--将"操作/表名/日期时间/插入字段"赋与消息
set @Msg = 'Inserted | tablefortrigger | ' + convert(varchar(20), getdate()) + ' | '
+(select convert(varchar(5), track)
+ ', ' + lastname + ', ' + firstname
from inserted)
--产生错误发送给事件查看器。
raiserror( 50005, 10, 1, @Msg)

  运行以下语句对触发器进行测试,然后查看事件日志:

Insert into tablefortrigger(lastname, firstname)
Values('Doe', 'John')

  如果你打开事件日志,你应该看到以下消息:


(图1)

  既然我们已经有办法写入事件日志了,那么让我们修改一下触发器,将数据写到一个文本文件中。这次改动还须添加另一个变量@CmdString,以及使用扩展储存过程xp_cmdshell。

  因为我们要写入文件系统,安全权限开始有影响了。所以,执行插入操作的用户必须具备该文本文件的读写权限。因此,设计一个C/S结构的应用程序供多用户运行,或许不是一个可行的解决方案。更合理的方案是,设计一个三层应用程序,由你的中间层组件对单用户数据库进行调用。在后一个方案中,对那个文本文件的权限管理其实比管理一个用户还容易。

Alter trigger TestTrigger on
tablefortrigger
for insert
as
Declare @Msg varchar(1000)
--储存将由xp_cmdshell执行的命令
Declare @CmdString varchar (2000)
set @_msg = ' insert | tablefortrigger | ' + convert ( varchar ( 20 ) , getdate ( ) ) + ' | ' + ( select convert ( varchar ( 5 ) , track ) + ' , ' + lastname + ' , ' + firstname from insert ) -
[99%]set @Msg = 'Inserted | tablefortrigger | ' + convert(varchar(20), getdate()) + ' | ' +(select convert(varchar(5), track) + ', ' + lastname + ', ' + firstname from inserted)
--产生错误发送给事件查看器。
raiserror( 50005, 10, 1, @Msg)
set @CmdString = 'echo ' + @Msg + ' >> C:\logtest.log'
--写到文本文件
exec master.dbo.xp_cmdshell @CmdString

  让我们对它进行测试,先运行前面的插入语句,然后打开C:\logtest.log文件查看结果:
  
Insert into tablefortrigger(lastname, firstname) Values('Doe', 'John')

  问题解决了,对不对?哦,还没完全解决。发生多次重复插入的事件是什么原因?在这个例子中,你必须分别地处理每条记录。为了达到这个目的,我们必须用一个会带来麻烦的游标来访问"隐蔽面"。在执行以前,我必须预先给予警告。你应当了解的是,当这个应用程序进行大规模地记录插入、更新或删除时要当心,因为它可能会耗费大量的内存。

  像你从下面看到的一样,这次我们在前面那个例子的基础上稍加调整,引入了一个游标,对该插入表的全部记录进行循环读取。每条记录分别插入一条线条,将各个事件区分开来。

ALTER trigger TestTrigger on tablefortrigger
for insert
as
Declare @Msg varchar(1000)
Declare @CmdString varchar (1000)
Declare GetinsertedCursor cursor for
Select 'Inserted | tablefortrigger | ' + convert(varchar(20), getdate()) + ' | '
+ convert(varchar(5), track)
+ ', ' + lastname + ', ' + firstname
from inserted

open GetinsertedCursor
Fetch Next from GetinsertedCursor
into @Msg

while @@fetch_status = 0
Begin
 raiserror( 50005, 10, 1, @Msg)
 Fetch Next from GetinsertedCursor
 into @Msg
 set @CmdString = 'echo ' + @Msg + ' >> C:\logtest.log'
 exec master.dbo.xp_cmdshell @CmdString
End
close Getinsertedcursor
deallocate GetInsertedCursor

  现在让我们执行重复多次插入测试:

Insert into tablefortrigger(lastname, firstname)
Select lastname, firstname from employees

  结论

  在继续完成之前,有些人认为必须考虑性能与安全问题。你将看到写入文本文件的开销,而对于一个每分钟处理5000项事务的数据库来说,这样大的开销也许不可接受。由于xp_cmdshell是在SQL外操作的,写入到文件的错误不会回滚事务。倘若入侵者使用一个隐蔽的途径来改变你的数据,这个事件不会被登记到那个文本文件中。不过事件日志将记录该次DML改动。作为一次最好的实践,各事件的编号应该被用于对照日志文件的各行记录,以便发现所有的差异。

  有很多种方法可以达到本文目标,上述脚本也可以有许多的变化。我希望你能接受这个脚本,然后作出改进并提出建议,使它更有效率。

转载于:https://www.cnblogs.com/omygod/archive/2006/11/24/570635.html

构造一个触发器用于插入数据之后插入 题目描述 构造一个触发器audit_log,在向employees_test中插入一条数据的时候,触发插入相关的数据到audit中。 CREATE TABLE employees_test( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50)... 阅读详情

相关推荐

C#在程序中创建数据库触发器并调用相关数据

C#在程序中创建数据库触发器并调用相关数据 CLR触发器

触发器实现数据库操作日志

首先建一个T_LOG用来保存日志,假设要监视的为T_TEST,则创建触发器的代码入下: create trigger TestTrigger on T_TEST for insert,update,deleteasSET NOCOUNT ONcreate table #t(EventType varchar(50),Parameters int ,EventInfo varchar(6

大头的专栏 594

触发器生成数据库操作日志

作为一名数据库管理员,你尽力以各部门熟知的不同格式,向各部门提供它们所需要的数据。你通常将MS Excel格式的数据递交到会计部门,或将数据以HTML报的形式呈现给普通用户。你们的系统安全管理员们则习惯于用文本阅读器或者事件查看器来查看日志。本文将介绍如何使用触发器,把DML(数据操作语言)对数据库中的特定数据的改动记录下来。

【MySQL】触发器

触发器是与有关的数据库对象,指在insert/update/delete之前(BEFORE)或之后(AFTER),触发并执行触发器中定义的SQL语句集合。触发器的这种特性可以协助应用在数据库端确保数据的完整性, 日志记录 , 数据校验等操作

qq_50675319的博客 1525

mysql 触发器 修改字段的值_触发器修改符合条件字段对应的值

--业务需求,通过触发器在新增时将姓名开始含有”T"英文的status状态改为1--1.创建createtabletest_user(idnumber,namenvarchar2(10),statusnumber);insertintotest_uservalues(1,'Hong',0);insertintotest_uservalues(2,'Qiang',0);co...

weixin_42565971的博客 1814

数据库原理学习——MySql触发器详解

触发器(Trigger)是数据库中的一种特殊存储程序,它绑定到某张(或视图)上,并在特定的数据库操作(如INSERTUPDATE或DELETE)发生时自动执行预定义的操作触发器无需手动调用,是一种事件驱动的机制。触发器目标检查是否是is_leave字段被更新为1。(示访客已离开)。②out_time距离当前时间已有 1 年以前。触发时机: 每当中的is_leave字段被更新为1时,该触发器会自动执行。触发器是一种强大的工具,用于增强数据库的自动化处理能力。

Future_yzx的博客 9055

数据库-触发器

有详细案例

m0_56223907的博客 1万+

触发器日志记录

首先先创建一个学生 create table student(id int primary key auto_increment,name varchar(20),sex enum("male","female"),age int); 创建一个触发器,不允许年龄小于0或者大于100 delimiter % create trigger student_age before insert on ...

weixin_42494845的博客 3520

数据库触发器

触发器做为数据库管理系统中的一种特殊对象,它可以在特定的数据库操作(如插入、更新、删除)发生时自动触发并执行相应的操作,有助于帮助实现数据的自动化处理和约束,但在使用时还需要谨慎考虑触发器的设计和影响。

2301_76255666的博客 3193

MySQL的触发器

1. MySQL触发器的概念与作用 触发器概念:触发器是一种特殊的存储过程,它在试图更改触发器所保护的数据时自动执行。 触发器与存储过程的异同 相同点:1. 触发器是一种特殊的存储过程,触发器和存储过程一样是一个能够完成特定功能、存储在数据库服务器上的SQL片段。 不同点:2. 存储器调用时需要调用SQL片段,而触发器不需要调用,当对数据库中的数据执行DML操作时自动触发这个SQL片段的执行,无需手动调用。 在MySQL中,只有执行insert,delete,update操作时才能触发触发器的执行; 触

A496608119的博客 5万+

SQLiteStudio数据库触发器管理:自动化数据操作

你是否还在手动编写重复的数据库校验逻辑?是否因数据变更不同步导致业务异常?SQLiteStudio的触发器功能可彻底解决这些问题。通过可视化界面创建触发器(Trigger),实现数据插入/更新/删除时的自动校验、关联操作日志记录,将重复工作交给数据库引擎处理。 读完本文你将掌握: - 触发器的3种核心应用场景(数据校验、级联操作、审计日志) - SQLiteStudio触发器设计器的完整使用流...

gitblog_00208的博客 1104

mysql 触发器 在插入之前修改插入的值,隐私字段加密加星号

需求场景: 根据数据安全法需要,数据库字段列如用户手机号,密码,银行账号等个人隐私信息需要加密存储,但是涉及插入和修改操作代码设计较多,不好在代码中修改,想到两种方案: 1,数据库层面:触发器数据插入或更新时,通过触发器用mysql的AES加密算法加密后替换原来的值再插入或者修改; 实现: 用Navicat定义触发器 BEGIN set new.phone = to_base64(AES_ENCRYPT( new.phone, 'test-2021-key' )); END new.phone

weixin_43655425的博客 3259

mysql触发器(同步数据增删改)

mysql触发器实现格同步

梦想照进现实 4310
上一篇: 办公室面试礼仪
下一篇: IT项目管理向沟通要效率
aebe49167
博客等级 码龄12年 14粉丝 163原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值