Come sapere l'utente che esegue un'azione di eliminazione su una tabella di controllo quando utilizza un accesso condiviso?


8

Informazioni di base:

  • Sto creando una raccolta di tabelle di controllo per tenere traccia degli aggiornamenti e delle eliminazioni in una serie di tabelle di dati per la mia app.
  • I record di controllo vengono creati tramite trigger.
  • Il DML nel database della mia app proviene generalmente da un accesso utilizzato da un servizio per accedere al database. Per questo motivo, penso che il risultato SYSTEM_USERsarà sempre lo stesso quando chiamato in un trigger.
  • La mia app non memorizza i dati utente al momento, anche UserIdse ogni volta che viene eseguito DML viene eseguita una stringa (eseguita esclusivamente nelle stored procedure).

Il problema che ho riscontrato è che quando un utente elimina un record, voglio sapere chi è stato. Poiché verrà eseguito dallo stesso accesso, non voglio vedere che tutte le azioni sono state eseguite dal servizio, voglio vedere quale utente lo ha fatto. Questo non è un problema su un aggiornamento, perché abbiamo ModifiedBycolonne che verranno aggiornate tramite un inviato UserIdsu aggiornamenti.

La domanda è: c'è un modo per impostare SYSTEM_USERo altrimenti ottenere le informazioni dell'utente nel trigger quando viene eseguita un'eliminazione?

L'idea "migliore" che ho in questo momento, anche se non sono ancora sicuro che sia una buona idea, è che nel servizio controllo per vedere se la corrente UserIdè nel database come utente e se non crea un utente obiettare per loro. Quindi eseguire le stored procedure con EXECUTE AS User = @UserId. Quindi, quando DML viene eseguito nella procedura memorizzata e il trigger si attiva, SYSTEM_USERdovrebbe restituire l'utente dal EXECUTE AS.


2
@RBarryYoung E quel meccanismo è l'oggetto della domanda. Il mio servizio sta entrando nel mio database facendo azioni per chiunque lo abbia chiamato e ho UserId disponibile. Devo capire come registrare quell'IdI nel caso di una cancellazione.
Jeremy Pridemore,

Abbastanza giusto, avrei dovuto leggere la tua domanda in modo più approfondito. Penso di avere una risposta per questo, ma potrei non essere in grado di pubblicarlo fino a tardi stasera.
RBarryYoung,

Risposte:


4

Mentre l'utilizzo EXECUTE AS User = @UserIdpuò essere l'opzione migliore (a seconda di altri problemi), ecco un approccio alternativo:

Nelle procedure memorizzate o in qualsiasi momento nella sessione SQL prima di DELETEeseguire il comando seguente:

SET CONTEXT_INFO @UserId

Quindi nel tuo trigger puoi recuperare questo valore con

SELECT @var = CAST(CAST(CONTEXT_INFO() As Varbinary(4)) As Int)

Ciò presenta alcuni svantaggi, il più importante dei quali è che non è possibile utilizzare facilmente CONTEXT_INFO per più di una cosa alla volta.


Abbiamo deciso di non avere le informazioni per ora. Se decidiamo di averlo, proverò prima questo. Grazie per l'idea
Jeremy Pridemore,

2

A seconda di come si modifica il contesto utente dall'accesso individuale all'accesso al servizio, è possibile che ORIGINAL_LOGIN () sia utile.

http://technet.microsoft.com/en-us/library/ms189492.aspx

"Questa funzione può essere utile per il controllo dell'identità del contesto di connessione originale. Mentre funzioni come SESSION_USER e CURRENT_USER restituiscono il contesto di esecuzione corrente, ORIGINAL_LOGIN restituisce l'identità dell'account di accesso che per primo si è connesso all'istanza di SQL Server in quella sessione."


Questa è una funzione chiara, grazie per averla menzionata. Sono abbastanza sicuro che quando ho un servizio in esecuzione e colpisco il database con lo stesso accesso del server ogni volta, ORIGINAL_LOGIN () restituirà sempre l'utente che il servizio sta utilizzando. Ti sembra corretto?
Jeremy Pridemore,

Sì, se si sta attraversando l'account del servizio per effettuare la connessione al database, ORIGINAL_LOGIN () sarebbe il servizio. Se cambi contesto dopo esserti connesso al database come te stesso, ORIGINAL_LOGIN () dovrebbe essere il tuo login.
RLF,

0

Puoi anche provare ad aggiungere Host_Nameai tuoi tavoli. Ho riscontrato situazioni in cui ho un accesso condiviso che di solito riesco a rintracciare un individuo in base al nome della sua macchina dal 95% delle volte che una persona lavora dalla propria macchina. Non sempre funziona, ma può essere un'informazione secondaria utile.

SELECT host_name FROM sys.dm_exec_sessions WHERE session_id = @@SPID

Sfortunatamente questo non funzionerà se si lavora con un'app Web in cui l'host sarà sempre l'applicazione Web stessa, ma potrebbe valere la pena provare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.