表中某个字段被某个存储过程修改

时间:2021-03-28 15:09:33
有一个表A,表A中有一个字段B被某个存储过程修改了。比如B的初始值为1,被某个存储过程改为了0,但是现在存储过程大概有1000多个,大神们有没有什么好的方法,可以监测到这个字段是被谁修改的。

14 个解决方案

#1


表里添加修改时间,修改者两个字段,每次修改,这两个值都要对应填写,同时,数据库添加日志表,每次修改,都要记日志,这样相互对照,就没跑了。

#2


如果存储过程能改,你可以在存储过程添加一段通用代码,写下修改日志
用object_name(@procid)获取当前存储过程的名字,写入log记录中

#3



如果现在值已经改成0了,那么很难知道之前是哪个存储过程改的。

如果希望以后能够知道是谁改了这个值,一般的办法如楼上说的,在数据中增加日志字段,可以大概知道是什么时间,哪个用户,哪个存储过程,把原来的值 多少 改成多少了,不过需要修改存储过程,另外需要修改表,工作量不小。

要么就是开启sql server的审核功能,可以记录系统中所有执行的sql语句,这个比较方便,但是如果系统本来就负载很高,不建议这么做,因为这样可能会影响系统正常使用。

还有一个办法是,用某些特殊的工具,比如 ApexSQL Log-SQL,如果事务日志还没有被覆盖,可以从日志中取出sql语句,那就能知道是哪个时间点,数据被改过了。

#4


引用 3 楼 yupeigu 的回复:
如果现在值已经改成0了,那么很难知道之前是哪个存储过程改的。

如果希望以后能够知道是谁改了这个值,一般的办法如楼上说的,在数据中增加日志字段,可以大概知道是什么时间,哪个用户,哪个存储过程,把原来的值 多少 改成多少了,不过需要修改存储过程,另外需要修改表,工作量不小。

要么就是开启sql server的审核功能,可以记录系统中所有执行的sql语句,这个比较方便,但是如果系统本来就负载很高,不建议这么做,因为这样可能会影响系统正常使用。

还有一个办法是,用某些特殊的工具,比如 ApexSQL Log-SQL,如果事务日志还没有被覆盖,可以从日志中取出sql语句,那就能知道是哪个时间点,数据被改过了。
我现在用ApexSQL 找到了一些日志,但是不知道怎么看是哪个存储过程修改的。难道是那个LSN号?

#5


引用 3 楼 yupeigu 的回复:
如果现在值已经改成0了,那么很难知道之前是哪个存储过程改的。

如果希望以后能够知道是谁改了这个值,一般的办法如楼上说的,在数据中增加日志字段,可以大概知道是什么时间,哪个用户,哪个存储过程,把原来的值 多少 改成多少了,不过需要修改存储过程,另外需要修改表,工作量不小。

要么就是开启sql server的审核功能,可以记录系统中所有执行的sql语句,这个比较方便,但是如果系统本来就负载很高,不建议这么做,因为这样可能会影响系统正常使用。

还有一个办法是,用某些特殊的工具,比如 ApexSQL Log-SQL,如果事务日志还没有被覆盖,可以从日志中取出sql语句,那就能知道是哪个时间点,数据被改过了。


引用 2 楼 ch21st 的回复:
如果存储过程能改,你可以在存储过程添加一段通用代码,写下修改日志
用object_name(@procid)获取当前存储过程的名字,写入log记录中
另外,我能不能写一个触发器,监测这个字段的值,如果变了,就写到一个日志表里,把当时的存储过程记录下来。

#6


引用 4 楼 moliyongheng 的回复:
Quote: 引用 3 楼 yupeigu 的回复:


如果现在值已经改成0了,那么很难知道之前是哪个存储过程改的。

如果希望以后能够知道是谁改了这个值,一般的办法如楼上说的,在数据中增加日志字段,可以大概知道是什么时间,哪个用户,哪个存储过程,把原来的值 多少 改成多少了,不过需要修改存储过程,另外需要修改表,工作量不小。

要么就是开启sql server的审核功能,可以记录系统中所有执行的sql语句,这个比较方便,但是如果系统本来就负载很高,不建议这么做,因为这样可能会影响系统正常使用。

还有一个办法是,用某些特殊的工具,比如 ApexSQL Log-SQL,如果事务日志还没有被覆盖,可以从日志中取出sql语句,那就能知道是哪个时间点,数据被改过了。
我现在用ApexSQL 找到了一些日志,但是不知道怎么看是哪个存储过程修改的。难道是那个LSN号?


那就没办法了。。。Lsn是日志序列号,并不能说明是哪个存储过程改的。

#7


引用 5 楼 moliyongheng 的回复:
Quote: 引用 3 楼 yupeigu 的回复:


如果现在值已经改成0了,那么很难知道之前是哪个存储过程改的。

如果希望以后能够知道是谁改了这个值,一般的办法如楼上说的,在数据中增加日志字段,可以大概知道是什么时间,哪个用户,哪个存储过程,把原来的值 多少 改成多少了,不过需要修改存储过程,另外需要修改表,工作量不小。

要么就是开启sql server的审核功能,可以记录系统中所有执行的sql语句,这个比较方便,但是如果系统本来就负载很高,不建议这么做,因为这样可能会影响系统正常使用。

还有一个办法是,用某些特殊的工具,比如 ApexSQL Log-SQL,如果事务日志还没有被覆盖,可以从日志中取出sql语句,那就能知道是哪个时间点,数据被改过了。


引用 2 楼 ch21st 的回复:
如果存储过程能改,你可以在存储过程添加一段通用代码,写下修改日志
用object_name(@procid)获取当前存储过程的名字,写入log记录中
另外,我能不能写一个触发器,监测这个字段的值,如果变了,就写到一个日志表里,把当时的存储过程记录下来。


这个也是一个办法,应该能实现

#8


引用 5 楼 moliyongheng 的回复:
Quote: 引用 3 楼 yupeigu 的回复:


如果现在值已经改成0了,那么很难知道之前是哪个存储过程改的。

如果希望以后能够知道是谁改了这个值,一般的办法如楼上说的,在数据中增加日志字段,可以大概知道是什么时间,哪个用户,哪个存储过程,把原来的值 多少 改成多少了,不过需要修改存储过程,另外需要修改表,工作量不小。

要么就是开启sql server的审核功能,可以记录系统中所有执行的sql语句,这个比较方便,但是如果系统本来就负载很高,不建议这么做,因为这样可能会影响系统正常使用。

还有一个办法是,用某些特殊的工具,比如 ApexSQL Log-SQL,如果事务日志还没有被覆盖,可以从日志中取出sql语句,那就能知道是哪个时间点,数据被改过了。


引用 2 楼 ch21st 的回复:
如果存储过程能改,你可以在存储过程添加一段通用代码,写下修改日志
用object_name(@procid)获取当前存储过程的名字,写入log记录中
另外,我能不能写一个触发器,监测这个字段的值,如果变了,就写到一个日志表里,把当时的存储过程记录下来。


这个方法我昨天试了下,仅记录数据变化没问题,但是我没找到获取调用修改数据的存储过程名称的办法

#9


引用 9 楼 ch21st 的回复:
Quote: 引用 5 楼 moliyongheng 的回复:

Quote: 引用 3 楼 yupeigu 的回复:


如果现在值已经改成0了,那么很难知道之前是哪个存储过程改的。

如果希望以后能够知道是谁改了这个值,一般的办法如楼上说的,在数据中增加日志字段,可以大概知道是什么时间,哪个用户,哪个存储过程,把原来的值 多少 改成多少了,不过需要修改存储过程,另外需要修改表,工作量不小。

要么就是开启sql server的审核功能,可以记录系统中所有执行的sql语句,这个比较方便,但是如果系统本来就负载很高,不建议这么做,因为这样可能会影响系统正常使用。

还有一个办法是,用某些特殊的工具,比如 ApexSQL Log-SQL,如果事务日志还没有被覆盖,可以从日志中取出sql语句,那就能知道是哪个时间点,数据被改过了。


引用 2 楼 ch21st 的回复:
如果存储过程能改,你可以在存储过程添加一段通用代码,写下修改日志
用object_name(@procid)获取当前存储过程的名字,写入log记录中
另外,我能不能写一个触发器,监测这个字段的值,如果变了,就写到一个日志表里,把当时的存储过程记录下来。


这个方法我昨天试了下,仅记录数据变化没问题,但是我没找到获取调用修改数据的存储过程名称的办法
我也没找到怎么获取当前的存储过程。。

#10


引用 8 楼 yupeigu 的回复:
Quote: 引用 5 楼 moliyongheng 的回复:

Quote: 引用 3 楼 yupeigu 的回复:


如果现在值已经改成0了,那么很难知道之前是哪个存储过程改的。

如果希望以后能够知道是谁改了这个值,一般的办法如楼上说的,在数据中增加日志字段,可以大概知道是什么时间,哪个用户,哪个存储过程,把原来的值 多少 改成多少了,不过需要修改存储过程,另外需要修改表,工作量不小。

要么就是开启sql server的审核功能,可以记录系统中所有执行的sql语句,这个比较方便,但是如果系统本来就负载很高,不建议这么做,因为这样可能会影响系统正常使用。

还有一个办法是,用某些特殊的工具,比如 ApexSQL Log-SQL,如果事务日志还没有被覆盖,可以从日志中取出sql语句,那就能知道是哪个时间点,数据被改过了。


引用 2 楼 ch21st 的回复:
如果存储过程能改,你可以在存储过程添加一段通用代码,写下修改日志
用object_name(@procid)获取当前存储过程的名字,写入log记录中
另外,我能不能写一个触发器,监测这个字段的值,如果变了,就写到一个日志表里,把当时的存储过程记录下来。


这个也是一个办法,应该能实现
没找到怎么获取 触发这个触发器的存储过程,版主大大 有啥好方法吗

#11


引用 11 楼 moliyongheng 的回复:
Quote: 引用 8 楼 yupeigu 的回复:

Quote: 引用 5 楼 moliyongheng 的回复:

Quote: 引用 3 楼 yupeigu 的回复:


如果现在值已经改成0了,那么很难知道之前是哪个存储过程改的。

如果希望以后能够知道是谁改了这个值,一般的办法如楼上说的,在数据中增加日志字段,可以大概知道是什么时间,哪个用户,哪个存储过程,把原来的值 多少 改成多少了,不过需要修改存储过程,另外需要修改表,工作量不小。

要么就是开启sql server的审核功能,可以记录系统中所有执行的sql语句,这个比较方便,但是如果系统本来就负载很高,不建议这么做,因为这样可能会影响系统正常使用。

还有一个办法是,用某些特殊的工具,比如 ApexSQL Log-SQL,如果事务日志还没有被覆盖,可以从日志中取出sql语句,那就能知道是哪个时间点,数据被改过了。


引用 2 楼 ch21st 的回复:
如果存储过程能改,你可以在存储过程添加一段通用代码,写下修改日志
用object_name(@procid)获取当前存储过程的名字,写入log记录中
另外,我能不能写一个触发器,监测这个字段的值,如果变了,就写到一个日志表里,把当时的存储过程记录下来。


这个也是一个办法,应该能实现
没找到怎么获取 触发这个触发器的存储过程,版主大大 有啥好方法吗


--1.建表
create table t(id int,v varchar(10))

insert into t values(1,'abc')


--2.存储过程
create proc proc_t(@id int,@v varchar(10))
as
update t
set v = @v
where id = @id

go

--3。日志表
create table tb_log(eventtype nvarchar(14),prama smallint,eventinfo nvarchar(1000),create_time datetime default getdate())
go


--4.触发器
create trigger dbo.trigger_t
on t
after update
as

insert into tb_log(eventtype,prama,eventinfo)
exec('DBCC INPUTBUFFER('+@@spid+')') 
go


--5.修改数据
exec proc_t 1,'123'
go

update t 
set v = 'xxx'
where id = 1 
go

--6.显示日志
select * from tb_log
/*
eventtype prama eventinfo create_time
Language Event 0 update t set v = 'xxx'where id = 1  2016-12-14 10:25:55.820
Language Event 0 exec proc_t 1,'123' 2016-12-14 10:26:05.840
*/

#12


                SELECT   allob.name ,
                        sch.name AS schemaname ,
                        allob.type ,
                        sqltext.definition AS sqltext 
               FROM     sys.objects allob
                        INNER JOIN sys.sql_modules sqltext ON allob.object_id = sqltext.object_id
                        INNER JOIN sys.schemas sch ON allob.schema_id = sch.schema_id
               WHERE    allob.type IN ( 'P', 'TR', 'F' )      ---存储过程、触发器、函数
                        AND sqltext.definition LIKE '%表名%'


如果自己没有做ddl语句日志,只能挨个排查了,先查出哪些存储过程里面的sql有包含这个表名,字段,update信息。

#13


引用 12 楼 yupeigu 的回复:
Quote: 引用 11 楼 moliyongheng 的回复:

Quote: 引用 8 楼 yupeigu 的回复:

Quote: 引用 5 楼 moliyongheng 的回复:

Quote: 引用 3 楼 yupeigu 的回复:


如果现在值已经改成0了,那么很难知道之前是哪个存储过程改的。

如果希望以后能够知道是谁改了这个值,一般的办法如楼上说的,在数据中增加日志字段,可以大概知道是什么时间,哪个用户,哪个存储过程,把原来的值 多少 改成多少了,不过需要修改存储过程,另外需要修改表,工作量不小。

要么就是开启sql server的审核功能,可以记录系统中所有执行的sql语句,这个比较方便,但是如果系统本来就负载很高,不建议这么做,因为这样可能会影响系统正常使用。

还有一个办法是,用某些特殊的工具,比如 ApexSQL Log-SQL,如果事务日志还没有被覆盖,可以从日志中取出sql语句,那就能知道是哪个时间点,数据被改过了。


引用 2 楼 ch21st 的回复:
如果存储过程能改,你可以在存储过程添加一段通用代码,写下修改日志
用object_name(@procid)获取当前存储过程的名字,写入log记录中
另外,我能不能写一个触发器,监测这个字段的值,如果变了,就写到一个日志表里,把当时的存储过程记录下来。


这个也是一个办法,应该能实现
没找到怎么获取 触发这个触发器的存储过程,版主大大 有啥好方法吗


--1.建表
create table t(id int,v varchar(10))

insert into t values(1,'abc')


--2.存储过程
create proc proc_t(@id int,@v varchar(10))
as
update t
set v = @v
where id = @id

go

--3。日志表
create table tb_log(eventtype nvarchar(14),prama smallint,eventinfo nvarchar(1000),create_time datetime default getdate())
go


--4.触发器
create trigger dbo.trigger_t
on t
after update
as

insert into tb_log(eventtype,prama,eventinfo)
exec('DBCC INPUTBUFFER('+@@spid+')') 
go


--5.修改数据
exec proc_t 1,'123'
go

update t 
set v = 'xxx'
where id = 1 
go

--6.显示日志
select * from tb_log
/*
eventtype prama eventinfo create_time
Language Event 0 update t set v = 'xxx'where id = 1  2016-12-14 10:25:55.820
Language Event 0 exec proc_t 1,'123' 2016-12-14 10:26:05.840
*/
谢谢 版主大大,已经在正式系统上加上触发器,靜等错误数据的出现了!

#1


表里添加修改时间,修改者两个字段,每次修改,这两个值都要对应填写,同时,数据库添加日志表,每次修改,都要记日志,这样相互对照,就没跑了。

#2


如果存储过程能改,你可以在存储过程添加一段通用代码,写下修改日志
用object_name(@procid)获取当前存储过程的名字,写入log记录中

#3



如果现在值已经改成0了,那么很难知道之前是哪个存储过程改的。

如果希望以后能够知道是谁改了这个值,一般的办法如楼上说的,在数据中增加日志字段,可以大概知道是什么时间,哪个用户,哪个存储过程,把原来的值 多少 改成多少了,不过需要修改存储过程,另外需要修改表,工作量不小。

要么就是开启sql server的审核功能,可以记录系统中所有执行的sql语句,这个比较方便,但是如果系统本来就负载很高,不建议这么做,因为这样可能会影响系统正常使用。

还有一个办法是,用某些特殊的工具,比如 ApexSQL Log-SQL,如果事务日志还没有被覆盖,可以从日志中取出sql语句,那就能知道是哪个时间点,数据被改过了。

#4


引用 3 楼 yupeigu 的回复:
如果现在值已经改成0了,那么很难知道之前是哪个存储过程改的。

如果希望以后能够知道是谁改了这个值,一般的办法如楼上说的,在数据中增加日志字段,可以大概知道是什么时间,哪个用户,哪个存储过程,把原来的值 多少 改成多少了,不过需要修改存储过程,另外需要修改表,工作量不小。

要么就是开启sql server的审核功能,可以记录系统中所有执行的sql语句,这个比较方便,但是如果系统本来就负载很高,不建议这么做,因为这样可能会影响系统正常使用。

还有一个办法是,用某些特殊的工具,比如 ApexSQL Log-SQL,如果事务日志还没有被覆盖,可以从日志中取出sql语句,那就能知道是哪个时间点,数据被改过了。
我现在用ApexSQL 找到了一些日志,但是不知道怎么看是哪个存储过程修改的。难道是那个LSN号?

#5


引用 3 楼 yupeigu 的回复:
如果现在值已经改成0了,那么很难知道之前是哪个存储过程改的。

如果希望以后能够知道是谁改了这个值,一般的办法如楼上说的,在数据中增加日志字段,可以大概知道是什么时间,哪个用户,哪个存储过程,把原来的值 多少 改成多少了,不过需要修改存储过程,另外需要修改表,工作量不小。

要么就是开启sql server的审核功能,可以记录系统中所有执行的sql语句,这个比较方便,但是如果系统本来就负载很高,不建议这么做,因为这样可能会影响系统正常使用。

还有一个办法是,用某些特殊的工具,比如 ApexSQL Log-SQL,如果事务日志还没有被覆盖,可以从日志中取出sql语句,那就能知道是哪个时间点,数据被改过了。


引用 2 楼 ch21st 的回复:
如果存储过程能改,你可以在存储过程添加一段通用代码,写下修改日志
用object_name(@procid)获取当前存储过程的名字,写入log记录中
另外,我能不能写一个触发器,监测这个字段的值,如果变了,就写到一个日志表里,把当时的存储过程记录下来。

#6


引用 4 楼 moliyongheng 的回复:
Quote: 引用 3 楼 yupeigu 的回复:


如果现在值已经改成0了,那么很难知道之前是哪个存储过程改的。

如果希望以后能够知道是谁改了这个值,一般的办法如楼上说的,在数据中增加日志字段,可以大概知道是什么时间,哪个用户,哪个存储过程,把原来的值 多少 改成多少了,不过需要修改存储过程,另外需要修改表,工作量不小。

要么就是开启sql server的审核功能,可以记录系统中所有执行的sql语句,这个比较方便,但是如果系统本来就负载很高,不建议这么做,因为这样可能会影响系统正常使用。

还有一个办法是,用某些特殊的工具,比如 ApexSQL Log-SQL,如果事务日志还没有被覆盖,可以从日志中取出sql语句,那就能知道是哪个时间点,数据被改过了。
我现在用ApexSQL 找到了一些日志,但是不知道怎么看是哪个存储过程修改的。难道是那个LSN号?


那就没办法了。。。Lsn是日志序列号,并不能说明是哪个存储过程改的。

#7


引用 5 楼 moliyongheng 的回复:
Quote: 引用 3 楼 yupeigu 的回复:


如果现在值已经改成0了,那么很难知道之前是哪个存储过程改的。

如果希望以后能够知道是谁改了这个值,一般的办法如楼上说的,在数据中增加日志字段,可以大概知道是什么时间,哪个用户,哪个存储过程,把原来的值 多少 改成多少了,不过需要修改存储过程,另外需要修改表,工作量不小。

要么就是开启sql server的审核功能,可以记录系统中所有执行的sql语句,这个比较方便,但是如果系统本来就负载很高,不建议这么做,因为这样可能会影响系统正常使用。

还有一个办法是,用某些特殊的工具,比如 ApexSQL Log-SQL,如果事务日志还没有被覆盖,可以从日志中取出sql语句,那就能知道是哪个时间点,数据被改过了。


引用 2 楼 ch21st 的回复:
如果存储过程能改,你可以在存储过程添加一段通用代码,写下修改日志
用object_name(@procid)获取当前存储过程的名字,写入log记录中
另外,我能不能写一个触发器,监测这个字段的值,如果变了,就写到一个日志表里,把当时的存储过程记录下来。


这个也是一个办法,应该能实现

#8


引用 5 楼 moliyongheng 的回复:
Quote: 引用 3 楼 yupeigu 的回复:


如果现在值已经改成0了,那么很难知道之前是哪个存储过程改的。

如果希望以后能够知道是谁改了这个值,一般的办法如楼上说的,在数据中增加日志字段,可以大概知道是什么时间,哪个用户,哪个存储过程,把原来的值 多少 改成多少了,不过需要修改存储过程,另外需要修改表,工作量不小。

要么就是开启sql server的审核功能,可以记录系统中所有执行的sql语句,这个比较方便,但是如果系统本来就负载很高,不建议这么做,因为这样可能会影响系统正常使用。

还有一个办法是,用某些特殊的工具,比如 ApexSQL Log-SQL,如果事务日志还没有被覆盖,可以从日志中取出sql语句,那就能知道是哪个时间点,数据被改过了。


引用 2 楼 ch21st 的回复:
如果存储过程能改,你可以在存储过程添加一段通用代码,写下修改日志
用object_name(@procid)获取当前存储过程的名字,写入log记录中
另外,我能不能写一个触发器,监测这个字段的值,如果变了,就写到一个日志表里,把当时的存储过程记录下来。


这个方法我昨天试了下,仅记录数据变化没问题,但是我没找到获取调用修改数据的存储过程名称的办法

#9


引用 9 楼 ch21st 的回复:
Quote: 引用 5 楼 moliyongheng 的回复:

Quote: 引用 3 楼 yupeigu 的回复:


如果现在值已经改成0了,那么很难知道之前是哪个存储过程改的。

如果希望以后能够知道是谁改了这个值,一般的办法如楼上说的,在数据中增加日志字段,可以大概知道是什么时间,哪个用户,哪个存储过程,把原来的值 多少 改成多少了,不过需要修改存储过程,另外需要修改表,工作量不小。

要么就是开启sql server的审核功能,可以记录系统中所有执行的sql语句,这个比较方便,但是如果系统本来就负载很高,不建议这么做,因为这样可能会影响系统正常使用。

还有一个办法是,用某些特殊的工具,比如 ApexSQL Log-SQL,如果事务日志还没有被覆盖,可以从日志中取出sql语句,那就能知道是哪个时间点,数据被改过了。


引用 2 楼 ch21st 的回复:
如果存储过程能改,你可以在存储过程添加一段通用代码,写下修改日志
用object_name(@procid)获取当前存储过程的名字,写入log记录中
另外,我能不能写一个触发器,监测这个字段的值,如果变了,就写到一个日志表里,把当时的存储过程记录下来。


这个方法我昨天试了下,仅记录数据变化没问题,但是我没找到获取调用修改数据的存储过程名称的办法
我也没找到怎么获取当前的存储过程。。

#10


引用 8 楼 yupeigu 的回复:
Quote: 引用 5 楼 moliyongheng 的回复:

Quote: 引用 3 楼 yupeigu 的回复:


如果现在值已经改成0了,那么很难知道之前是哪个存储过程改的。

如果希望以后能够知道是谁改了这个值,一般的办法如楼上说的,在数据中增加日志字段,可以大概知道是什么时间,哪个用户,哪个存储过程,把原来的值 多少 改成多少了,不过需要修改存储过程,另外需要修改表,工作量不小。

要么就是开启sql server的审核功能,可以记录系统中所有执行的sql语句,这个比较方便,但是如果系统本来就负载很高,不建议这么做,因为这样可能会影响系统正常使用。

还有一个办法是,用某些特殊的工具,比如 ApexSQL Log-SQL,如果事务日志还没有被覆盖,可以从日志中取出sql语句,那就能知道是哪个时间点,数据被改过了。


引用 2 楼 ch21st 的回复:
如果存储过程能改,你可以在存储过程添加一段通用代码,写下修改日志
用object_name(@procid)获取当前存储过程的名字,写入log记录中
另外,我能不能写一个触发器,监测这个字段的值,如果变了,就写到一个日志表里,把当时的存储过程记录下来。


这个也是一个办法,应该能实现
没找到怎么获取 触发这个触发器的存储过程,版主大大 有啥好方法吗

#11


引用 11 楼 moliyongheng 的回复:
Quote: 引用 8 楼 yupeigu 的回复:

Quote: 引用 5 楼 moliyongheng 的回复:

Quote: 引用 3 楼 yupeigu 的回复:


如果现在值已经改成0了,那么很难知道之前是哪个存储过程改的。

如果希望以后能够知道是谁改了这个值,一般的办法如楼上说的,在数据中增加日志字段,可以大概知道是什么时间,哪个用户,哪个存储过程,把原来的值 多少 改成多少了,不过需要修改存储过程,另外需要修改表,工作量不小。

要么就是开启sql server的审核功能,可以记录系统中所有执行的sql语句,这个比较方便,但是如果系统本来就负载很高,不建议这么做,因为这样可能会影响系统正常使用。

还有一个办法是,用某些特殊的工具,比如 ApexSQL Log-SQL,如果事务日志还没有被覆盖,可以从日志中取出sql语句,那就能知道是哪个时间点,数据被改过了。


引用 2 楼 ch21st 的回复:
如果存储过程能改,你可以在存储过程添加一段通用代码,写下修改日志
用object_name(@procid)获取当前存储过程的名字,写入log记录中
另外,我能不能写一个触发器,监测这个字段的值,如果变了,就写到一个日志表里,把当时的存储过程记录下来。


这个也是一个办法,应该能实现
没找到怎么获取 触发这个触发器的存储过程,版主大大 有啥好方法吗


--1.建表
create table t(id int,v varchar(10))

insert into t values(1,'abc')


--2.存储过程
create proc proc_t(@id int,@v varchar(10))
as
update t
set v = @v
where id = @id

go

--3。日志表
create table tb_log(eventtype nvarchar(14),prama smallint,eventinfo nvarchar(1000),create_time datetime default getdate())
go


--4.触发器
create trigger dbo.trigger_t
on t
after update
as

insert into tb_log(eventtype,prama,eventinfo)
exec('DBCC INPUTBUFFER('+@@spid+')') 
go


--5.修改数据
exec proc_t 1,'123'
go

update t 
set v = 'xxx'
where id = 1 
go

--6.显示日志
select * from tb_log
/*
eventtype prama eventinfo create_time
Language Event 0 update t set v = 'xxx'where id = 1  2016-12-14 10:25:55.820
Language Event 0 exec proc_t 1,'123' 2016-12-14 10:26:05.840
*/

#12


                SELECT   allob.name ,
                        sch.name AS schemaname ,
                        allob.type ,
                        sqltext.definition AS sqltext 
               FROM     sys.objects allob
                        INNER JOIN sys.sql_modules sqltext ON allob.object_id = sqltext.object_id
                        INNER JOIN sys.schemas sch ON allob.schema_id = sch.schema_id
               WHERE    allob.type IN ( 'P', 'TR', 'F' )      ---存储过程、触发器、函数
                        AND sqltext.definition LIKE '%表名%'


如果自己没有做ddl语句日志,只能挨个排查了,先查出哪些存储过程里面的sql有包含这个表名,字段,update信息。

#13


引用 12 楼 yupeigu 的回复:
Quote: 引用 11 楼 moliyongheng 的回复:

Quote: 引用 8 楼 yupeigu 的回复:

Quote: 引用 5 楼 moliyongheng 的回复:

Quote: 引用 3 楼 yupeigu 的回复:


如果现在值已经改成0了,那么很难知道之前是哪个存储过程改的。

如果希望以后能够知道是谁改了这个值,一般的办法如楼上说的,在数据中增加日志字段,可以大概知道是什么时间,哪个用户,哪个存储过程,把原来的值 多少 改成多少了,不过需要修改存储过程,另外需要修改表,工作量不小。

要么就是开启sql server的审核功能,可以记录系统中所有执行的sql语句,这个比较方便,但是如果系统本来就负载很高,不建议这么做,因为这样可能会影响系统正常使用。

还有一个办法是,用某些特殊的工具,比如 ApexSQL Log-SQL,如果事务日志还没有被覆盖,可以从日志中取出sql语句,那就能知道是哪个时间点,数据被改过了。


引用 2 楼 ch21st 的回复:
如果存储过程能改,你可以在存储过程添加一段通用代码,写下修改日志
用object_name(@procid)获取当前存储过程的名字,写入log记录中
另外,我能不能写一个触发器,监测这个字段的值,如果变了,就写到一个日志表里,把当时的存储过程记录下来。


这个也是一个办法,应该能实现
没找到怎么获取 触发这个触发器的存储过程,版主大大 有啥好方法吗


--1.建表
create table t(id int,v varchar(10))

insert into t values(1,'abc')


--2.存储过程
create proc proc_t(@id int,@v varchar(10))
as
update t
set v = @v
where id = @id

go

--3。日志表
create table tb_log(eventtype nvarchar(14),prama smallint,eventinfo nvarchar(1000),create_time datetime default getdate())
go


--4.触发器
create trigger dbo.trigger_t
on t
after update
as

insert into tb_log(eventtype,prama,eventinfo)
exec('DBCC INPUTBUFFER('+@@spid+')') 
go


--5.修改数据
exec proc_t 1,'123'
go

update t 
set v = 'xxx'
where id = 1 
go

--6.显示日志
select * from tb_log
/*
eventtype prama eventinfo create_time
Language Event 0 update t set v = 'xxx'where id = 1  2016-12-14 10:25:55.820
Language Event 0 exec proc_t 1,'123' 2016-12-14 10:26:05.840
*/
谢谢 版主大大,已经在正式系统上加上触发器,靜等错误数据的出现了!