2010-01-07 2 views
0

Mon système ERP dispose d'un système de suivi de suppression à moitié cuit qui insère les informations suivantes dans une table appelée M2MDeleteLog. J'ai laissé de côté des colonnes inutiles comme RecordId pour la simplicité.Tentative d'audit des suppressions avec un système à moitié cuit

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 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 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 

Malheureusement, la plupart des informations pertinentes se trouvent dans 1 champ de texte. La première étape consiste à extraire l'utilisateur (D.STEIN), l'écran (SOMAST) et l'écran (frmso) du champ LogInfo. Cette partie est relativement facile.

Ce que je veux faire est de créer un travail planifié, qui s'exécute toutes les 15 minutes environ, pour rechercher une activité suspecte. Je définirais une activité suspecte comme étant 3 suppressions dans un intervalle de 15 minutes par utilisateur.

Mais attendez! Il y a plus!

Dans les données que j'ai fournies, il n'y a que 3 événements de suppression, chacun étant espacé de moins d'une minute. Je définirais un nouvel événement de suppression au moins 20 secondes après le dernier.

Comment est-ce que je peux évaluer le LogDate, en remontant 15 minutes, comptant les événements de suppression par utilisateur, ainsi je peux informer l'admin quand plus de 3 sont enregistrés pour un certain utilisateur?

Répondre

1

EDIT: ah, tirer, je viens de remarquer la balise SQL2K. L'exemple 1 devrait toujours fonctionner, mais l'exemple 2 ne fonctionnera pas. Hmm, comment pourrions-nous remédier à cela .....?

EDIT: fixe!

EDIT: encore mieux!

Asuming vous avez analysé le champ de texte, cette requête vous donnera une suppression qui a été précédée d'au moins 2 suppressions par le même utilisateur dans une fenêtre de 15 minutes:

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 
) 

(Vous devriez avoir un indice on (UserName LogDate), btw)

En ce qui concerne le comptage des suppressions espacées de 20 secondes ou plus, ce n'est pas si simple. Quelque chose comme ça peut-être?

SQL2K, basé sur this par 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 

Dans la CROSS APPLY, j'ai utilisé TOP 1 LogDate...ORDER BY LogDate DESC plutôt que MAX(LogDate) vous pouvez donc ajouter d'autres champs à l'ensemble de résultats, comme RecordId, Workstation, etc.

Questions connexes