触发器问题

全栈深入 阿里巴巴 高级技术专家  2010-09-21 01:11:42
我们知道在ms sql里面触发器根据触发的种类有三种INSERT,DELETE,UPDATE,当我们新增/修改/删除一个数据表中记录的数据时,触发器都会被激发.从而执行相应触发器里面的脚本.现在的问题是:

1.问题1:有没有什么办法取得引起触发的Insert/Update/Delete原始语句?

比如说有一个Table名为User,有以下一些数据
ID UserName Sex Age High Address Tel Fax
-------------------------------------------------------------------------
1 张三 男 20 170 深圳 123456 123456
2 李四 男 21 172 北京 823456 223456
3 王五 男 22 179 深圳 923456 323456
4 赵六 男 24 168 上海 623456 423456
5 马七 男 30 180 成都 723456 523456
6 侯八 男 52 178 深圳 423456 623456


有一个未知的更新类型更新未知的字段值:
Insert user(UserName,Sex) values ('John','男')或者
Update User set High = 185 where ID = 3
或者其它的.

在触发器里面怎么取得
"Insert user(UserName,Sex) values ('John','男')"
"Update User set High = 185 where ID = 3"
的字符串


2.问题2:更新一个未知表时能不能获取被更新的未知字段的前后变化值
比如说上面一个表中,当Update User set High = 185,Sex ='女' where ID = 3时
我要取High变动之前的值和变动之后的值,自动在日志记录的表里面产生一条这些什么表由什么值变动到什么值的记录,如下,怎么实现?
ID TableName ChangeDetail
1 User 修改内容:Hign值:179 => 185 ,Sex: 男 => 女


注意哦,表名和被更新的字段名是未知不确定的哦


...全文
93 点赞 收藏 15
写回复
15 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
全栈深入 2010-11-11
自己顶起来
回复
全栈深入 2010-10-08
[Quote=引用 13 楼 beirut 的回复:]
引用 11 楼 nofc2006 的回复:
上面所有的答案只回答了问题1,获取到了最后次执行的sql语句。
对于问题2,有没有什么办法?

得到如下的结果:(自动解析变动的内容,获得变动前的值 和 变动后的值)

ID TableName ChangeDetail
1 User 修改内容:Hign值:179 => 185 ,Sex: 男 => 女

如果是05或08 就好办了 使……
[/Quote]


我在sql2005/sql2008里面试了,可以实现一部分功能,但是要动态取得变动的字段,不太好取,只能把字段事先写死.

update User set Hign=185,Sex= '女' output Deleted.Hign,Inserted.Hign,Deleted.Sex,Inserted.Sex


得到如下的结果
High High Sex Sex
-------------------------------
175 185 男 女


现在的问题是,在不知道更新了哪个列的前提下,我怎么把更新字段前后的内容捕获到,并且存放在一个 记录变动表的一个字段当中去呢?得到如下类似的结果:

ID TableName ChangeDetail
1 User 修改内容:Hign值:179 => 185 ,Sex: 男 => 女
回复
小_爱 2010-09-24
[Quote=引用 11 楼 nofc2006 的回复:]
上面所有的答案只回答了问题1,获取到了最后次执行的sql语句。
对于问题2,有没有什么办法?

得到如下的结果:(自动解析变动的内容,获得变动前的值 和 变动后的值)

ID TableName ChangeDetail
1 User 修改内容:Hign值:179 => 185 ,Sex: 男 => 女
[/Quote]
如果是05或08 就好办了 使用 output 字句搞定
回复
小_爱 2010-09-24
[Quote=引用 9 楼 ws_hgo 的回复:]
引用 7 楼 sdhdy 的回复:

楼主这个问题,建议实现的时候放到前台程序里去控制。
关于触发器,可以参考一下这个。
http://blog.csdn.net/sdhdy/archive/2009/06/07/4249668.aspx

处处
好久不见
[/Quote]
这名字。。。。。。。。。。
回复
全栈深入 2010-09-24
上面所有的答案只回答了问题1,获取到了最后次执行的sql语句。
对于问题2,有没有什么办法?

得到如下的结果:(自动解析变动的内容,获得变动前的值 和 变动后的值)

ID TableName ChangeDetail
1 User 修改内容:Hign值:179 => 185 ,Sex: 男 => 女
回复
全栈深入 2010-09-21
[Quote=引用 6 楼 nofc2006 的回复:]
引用 4 楼 happyflystone 的回复:
DBCC可以


翻阅了一下MSDN,与DBCC相关函数有以下一些,好像没有找到DBCC获取执行的sql脚本的函数啊?

SQL code

--信息语句
DBCC INPUTBUFFER
DBCC SHOWCONTIG
DBCC OPENTRAN
DBCC SQLPERF
DBCC OUTPUTBUFFER……
[/Quote]


发现了, DBCC INPUTBUFFER (@@spid); 可以查询当前会话查询最后一次的查询语句
回复
ws_hgo 2010-09-21
[Quote=引用 7 楼 sdhdy 的回复:]

楼主这个问题,建议实现的时候放到前台程序里去控制。
关于触发器,可以参考一下这个。
http://blog.csdn.net/sdhdy/archive/2009/06/07/4249668.aspx
[/Quote]
处处
好久不见
回复
放着代码,看不到就没办法了
回复
sdhdy 2010-09-21
楼主这个问题,建议实现的时候放到前台程序里去控制。
关于触发器,可以参考一下这个。
http://blog.csdn.net/sdhdy/archive/2009/06/07/4249668.aspx
回复
全栈深入 2010-09-21
[Quote=引用 4 楼 happyflystone 的回复:]
DBCC可以
[/Quote]

翻阅了一下MSDN,与DBCC相关函数有以下一些,好像没有找到DBCC获取执行的sql脚本的函数啊?

--信息语句
DBCC INPUTBUFFER
DBCC SHOWCONTIG
DBCC OPENTRAN
DBCC SQLPERF
DBCC OUTPUTBUFFER
DBCC TRACESTATUS
DBCC PROCCACHE
DBCC USEROPTIONS
DBCC SHOW_STATISTICS


--验证语句
DBCC CHECKALLOC
DBCC CHECKFILEGROUP
DBCC CHECKCATALOG
DBCC CHECKIDENT
DBCC CHECKCONSTRAINTS
DBCC CHECKTABLE
DBCC CHECKDB


--维护语句
DBCC CLEANTABLE
DBCC INDEXDEFRAG

DBCC DBREINDEX
DBCC SHRINKDATABASE

DBCC DROPCLEANBUFFERS
DBCC SHRINKFILE

DBCC FREEPROCCACHE
DBCC UPDATEUSAGE


--杂项语句
DBCC dllname (FREE)
DBCC TRACEOFF
DBCC HELP
DBCC TRACEON


回复
zsh0809 2010-09-21
[Quote=引用 3 楼 billpu 的回复:]

海爷空间有的http://blog.csdn.net/Haiwer/archive/2008/10/04/3016270.aspx
[/Quote]
...
回复
-狙击手- 2010-09-21
DBCC可以
回复
billpu 2010-09-21
海爷空间有的http://blog.csdn.net/Haiwer/archive/2008/10/04/3016270.aspx
回复
changjiangzhibin 2010-09-21
同一楼,那里好详细,不说了,跟一贴
回复
SQL77 2010-09-21
海爷空间有http://blog.csdn.net/Haiwer/archive/2008/10/04/3016270.aspx
回复
相关推荐
发帖
疑难问题
创建于2007-09-28

2.1w+

社区成员

MS-SQL Server 疑难问题
申请成为版主
帖子事件
创建了帖子
2010-09-21 01:11
社区公告
暂无公告