Trying to audit deletions with a half baked system
My ERP system has a half baked deletion tracking system which inserts the following info into a table called M2MDeleteLog. I have left out unnecessary columns such as RecordId for simplicity.
LogDate Workstation LogInfo
1/7/2010 11:01:51 TECH-M2MTEST Deleting 1 Rows From SOMast
1/7/2010 11:01:51 TECH-M2MTEST Unqualified M2MDELETE by D.STEIN in SOMAST from form frmSo Parameters: NONE
1/7/2010 11:01:51 TECH-M2MTEST Unqualified M2MDELETE by D.STEIN in SODBOM from form frmSo Parameters: NONE
1/7/2010 11:01:51 TECH-M2MTEST Unqualified M2MDELETE by D.STEIN in SODBOM from form frmSo Parameters: NONE
1/7/2010 11:01:51 TECH-M2MTEST Unqualified M2MDELETE by D.STEIN in SORELS from form frmSo Parameters: NONE
1/7/2010 11:01:51 TECH-M2MTEST Unqualified M2MDELETE by D.STEIN in SORELS from form frmSo Parameters: NONE
1/7/2010 11:01:51 TECH-M2MTEST Unqualified M2MDELETE by D.STEIN in SOITEM from form frmSo Parameters: NONE
1/7/2010 11:01:51 TECH-M2MTEST Deleting 1 Rows From SOItem
1/7/2010 11:01:51 TECH-M2MTEST Unqualified M2MDELETE by D.STEIN in SOITEM from form frmSo Parameters: NONE
1/7/2010 11:01:51 TECH-M2MTEST Deleting 1 Rows From SOItem
1/7/2010 11:01:00 TECH-M2MTEST Unqualified M2MDELETE by D.STEIN in SOMAST from form frmSo Parameters: NONE
1/7/2010 11:01:00 TECH-M2MTEST Deleting 1 Rows From SOMast
1/7/2010 11:01:00 TECH-M2MTEST Unqu开发者_如何学JAVAalified M2MDELETE by D.STEIN in SODBOM from form frmSo Parameters: NONE
1/7/2010 11:01:00 TECH-M2MTEST Unqualified M2MDELETE by D.STEIN in SODBOM from form frmSo Parameters: NONE
1/7/2010 11:01:00 TECH-M2MTEST Unqualified M2MDELETE by D.STEIN in SORELS from form frmSo Parameters: NONE
1/7/2010 11:01:00 TECH-M2MTEST Unqualified M2MDELETE by D.STEIN in SORELS from form frmSo Parameters: NONE
1/7/2010 11:01:00 TECH-M2MTEST Unqualified M2MDELETE by D.STEIN in SOITEM from form frmSo Parameters: NONE
1/7/2010 11:01:00 TECH-M2MTEST Deleting 1 Rows From SOItem
1/7/2010 11:01:00 TECH-M2MTEST Unqualified M2MDELETE by D.STEIN in SOITEM from form frmSo Parameters: NONE
1/7/2010 11:01:00 TECH-M2MTEST Deleting 1 Rows From SOItem
1/7/2010 11:00:29 TECH-M2MTEST Unqualified M2MDELETE by D.STEIN in SOMAST from form frmSo Parameters: NONE
1/7/2010 11:00:29 TECH-M2MTEST Deleting 1 Rows From SOMast
1/7/2010 11:00:28 TECH-M2MTEST Unqualified M2MDELETE by D.STEIN in SODBOM from form frmSo Parameters: NONE
1/7/2010 11:00:28 TECH-M2MTEST Unqualified M2MDELETE by D.STEIN in SODBOM from form frmSo Parameters: NONE
1/7/2010 11:00:28 TECH-M2MTEST Unqualified M2MDELETE by D.STEIN in SORELS from form frmSo Parameters: NONE
1/7/2010 11:00:28 TECH-M2MTEST Unqualified M2MDELETE by D.STEIN in SORELS from form frmSo Parameters: NONE
1/7/2010 11:00:28 TECH-M2MTEST Deleting 1 Rows From SOItem
1/7/2010 11:00:28 TECH-M2MTEST Unqualified M2MDELETE by D.STEIN in SOITEM from form frmSo Parameters: NONE
1/7/2010 11:00:28 TECH-M2MTEST Unqualified M2MDELETE by D.STEIN in SOITEM from form frmSo Parameters: NONE
1/7/2010 11:00:28 TECH-M2MTEST Deleting 1 Rows From SOItem
Unfortunately, most of the pertinent information is in 1 text field. The first step is to pull the user (D.STEIN), screen (SOMAST), and screen (frmso) from the LogInfo field. That part is relatively easy.
What I want to do is to create a scheduled job, which runs every 15 minutes or so, to look for suspicious activity. I would define suspicious activity as being 3 deletions in a 15 minute interval per user.
But wait! There's More!
In the data I provided, there are only 3 deletion events, each spaced less than a minute apart. I would define a new deletion event being at least 20 seconds after the last one.
How can I evaluate the LogDate, going back 15 minutes, counting the deletion events per user, so I can notify the admin when more than 3 are recorded for a certain user?
EDIT: ah, shoot, I just noticed the SQL2K tag. Example 1 should still work, but example 2 will not. Hmm, how could we remedy this.....?
EDIT: fixed!
EDIT: even better!
Asuming you have parsed the text field, this query will give you any deletion that was preceded by at least 2 deletions by the same user in a 15 minute window:
SELECT UserName, LogDate
FROM #parsed_data a
WHERE EXISTS (
SELECT * FROM #parsed_data b
WHERE a.UserName = b.UserName
AND b.LogDate < a.LogDate
AND DATEDIFF(MINUTE,b.LogDate,a.LogDate) <= 15
HAVING COUNT(*) >= 2
)
(You should have an index on (UserName LogDate), btw)
As far as only counting deletes spaced apart by 20 seconds or more, that's not so simple. Something like this perhaps?
SQL2K, based on this by Quassnoi:
SELECT a.UserName, a.LogDate, b.LogDate, c.LogDate --, etc
FROM #parsed_data a
JOIN #parsed_data b
ON b.RecordId = (
SELECT TOP 1 b0.RecordId FROM #parsed_data b0
WHERE b0.UserName = a.UserName AND b0.LogDate < a.LogDate1
AND DATEDIFF(MINUTE,b0.LogDate,a.LogDate) <= 15
AND DATEDIFF(SECOND,b0.LogDate,a.LogDate) >= 20
ORDER BY b0.LogDate DESC
)
JOIN #parsed_data c
ON c.RecordId = (
SELECT TOP 1 c0.RecordId FROM #parsed_data c0
WHERE c0.UserName = b.UserName AND c0.LogDate < b.LogDate
AND DATEDIFF(MINUTE,c0.LogDate,a.LogDate) <= 15
AND DATEDIFF(SECOND,c0.LogDate,b.LogDate) >= 20
ORDER BY c0.LogDate DESC
)
SQL2005/2008, CROSS APPLY:
SELECT a.UserName
, a.LogDate AS LogDate0 -- current
, b.LogDate AS LogDate1 -- prior
, c.LogDate as LogDate2 -- prior prior
FROM #parsed_data a
CROSS APPLY (
SELECT TOP 1 b.LogDate FROM #parsed_data b
WHERE b.UserName = a.UserName
AND b.LogDate < a.LogDate
AND DATEDIFF(MINUTE,b.LogDate,a.LogDate) <= 15
AND DATEDIFF(SECOND,b.LogDate,a.LogDate) >= 20
ORDER BY b.LogDate DESC
) b
CROSS APPLY (
SELECT TOP 1 c.LogDate FROM #parsed_data c
WHERE c.UserName = a.UserName
AND c.LogDate < b.LogDate
AND DATEDIFF(MINUTE,c.LogDate,a.LogDate) <= 15
AND DATEDIFF(SECOND,c.LogDate,b.LogDate) >= 20
ORDER BY c.LogDate DESC
) c
In the CROSS APPLY, I used TOP 1 LogDate...ORDER BY LogDate DESC
rather than MAX(LogDate)
so you can add other fields to the result set, like RecordId, Workstation, etc.
精彩评论