none
Nome utente collegato che esegue istruzione insert o update. RRS feed

  • Domanda

  • Buongiorno a tutti,

    Ho necessità di inserire nelle tabelle di sql server il nome dell'utente e la data  di chi esegue una modifica o un nuovo inserimento usando dei triggers.

    Ora se uso SYSTEM_USER mi restituisce sempre il nome del computer e il nome dell'utente windows collegato(NomePC\UtenteWindows).

    Ho però degli utenti che si collegano da un programma usando nome utente e relativa password (da Ms Access). 

    Quale comando mi permette di conoscere il nome dell'utente che sta eseguendo la modifica o l'inserimento?

    Grazie a chi mi può aiutare.

    Marco Dell'Oca

    /****** Object:  Trigger [dbo].[TRG_immagini]    Script Date: 03/05/2019 15:46:02 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    
    ALTER TRIGGER [dbo].[TRG_immagini]
    ON  [dbo].[Immagini] 
       for  INSERT, UPDATE
    AS 
    BEGIN
    	SET NOCOUNT ON;
        update dbo.immagini
        set datainser = getdate(),
    	 utente = SYSTEM_USER
    	from inserted
    	where dbo.immagini.IDimmagine = inserted.IDimmagine
    END
    
    
    SET ANSI_NULLS ON


    venerdì 3 maggio 2019 13:49

Risposte

  • io ti ho dato questo suggerimento perchè anch'io sono stato costretto ad adottare questa soluzione in alcune mie applicazioni perchè ritengo che quello che conta sia raggiungere il risultato che serve.

    buon lavoro


    Edoardo Benussi
    Microsoft MVP - Cloud and Datacenter Management
    e[dot]benussi[at]outlook[dot]it

    • Contrassegnato come risposta Marco Dell'Oca sabato 1 giugno 2019 17:58
    lunedì 27 maggio 2019 07:01
    Moderatore

Tutte le risposte

  • "Ho però degli utenti che si collegano da un programma usando nome utente e relativa password (da Ms Access). "

    Cosa intendi? Dipende come viene effettuata la connessione a SQL dall'applicazione (anche MS Access): se usi un ODBC sul client, dipende come è configurato quell'ODBC.
    Se la connessione viene aperta via VB dipende come è costruita la stringa.


    Igor MCSE (once upon a time) -- http://jenga.wordpress.com

    • Contrassegnato come risposta Marco Dell'Oca sabato 4 maggio 2019 13:05
    • Contrassegno come risposta annullato Marco Dell'Oca domenica 5 maggio 2019 14:08
    venerdì 3 maggio 2019 14:02
  • Grazie Igor per la risposta,

    le stringhe di connessione usate sono le seguenti:

        If Me.chk_UseNT.Value = 0 Then
            'Not trasted
            ODBCstrconnect = "ODBC;Driver=SQL Server" _
                & ";Trusted_Connection=no" _
                & ";SERVER=" & strServer _
                & ";DATABASE=" & strDatabase _
                & ";UID=" & strUserID _
                & ";PWD=" & strPassword _
                & ";LANGUAGE=Italiano"
                        
            oledbstrconnect = "Provider=SQLOLEDB" _
                & ";Trusted_Connection=no" _
                & ";Persist Security Info = false" _
                & ";Data Source=" & strServer _
                & ";Initial Catalog=" & strDatabase _
                & ";User ID=" & strUserID _
                & ";Password=" & strPassword
    
        Else
            'Trasted connection
            ODBCstrconnect = "ODBC;Driver=SQL Server" _
                & ";TRUSTED_CONNECTION=YES" _
                & ";SERVER=" & strServer _
                & ";DATABASE=" & strDatabase _
                & ";LANGUAGE=Italiano"
            
            oledbstrconnect = "Provider=SQLOLEDB" _
                & ";Integrated Security=SSPI" _
                & ";Data Source=" & strServer _
                & ";Initial Catalog=" & strDatabase
                
        End If

    In pratica il programma (Ms Access) si connette ad un server, ad un'istanza e può eseguire connessioni sia trasted che not trasted.

    Perchè questa domanda?  <Cosa Intendi?>

    Grazie ancora 

    Marco Dell'Oca

    venerdì 3 maggio 2019 14:16
  • Igor buongiorno,

    Ho modificato le stringhe di connessione ed ora il trigger mi restituisce correttamente il nome dell'utente che esegue l'operazione.

    Grazie ancora 

    Marco Dell'Oca

            'Not trasted
            ODBCstrconnectnot = "ODBC;Driver=SQL Server Native Client 11.0" _
                & ";Trusted_Connection=no" _
                & ";SERVER=" & "WIN2016NEW\SQL2016" _
                & ";DATABASE=" & "dmsoft" _
                & ";UID=" & "Marco" _
                & ";PWD=" & "Li5Pi5P1" _
                & ";LANGUAGE=Italiano"
    
            oledbstrconnectnot = "Provider=SQLNCLI11" _
                & ";Trusted_Connection=no" _
                & ";Persist Security Info = false" _
                & ";Data Source=" & "WIN2016NEW\SQL2016" _
                & ";Initial Catalog=" & "dmsoft" _
                & ";User ID=" & "Marco" _
                & ";Password=" & "Li5Pi5P1"
    
    
            'Trasted connection
            ODBCstrconnect = "ODBC;Driver=SQL Server Native Client 11.0" _
                & ";TRUSTED_CONNECTION=YES" _
                & ";SERVER=" & "WIN2016NEW\SQL2016" _
                & ";DATABASE=" & "dmsoft" _
                & ";LANGUAGE=Italiano"
            
            oledbstrconnect = "Provider=SQLNCLI11" _
                & ";Integrated Security=SSPI" _
                & ";Data Source=" & "WIN2016NEW\SQL2016" _
                & ";Initial Catalog=" & "dmsoft"

    sabato 4 maggio 2019 13:14
  • Buongiorno Igor,

    pensavo di aver risolto il problema ma, non è così.

    Dopo aver modificato le stringhe di connessione sto avendo un sacco di problemi con Ms Access.

    Non salva più i records, non salva le variazioni,... ecc.

    Penso quindi che non posso modificare le stringhe di connessione.

    C'è qualche altra soluzione?

    Grazie ancora 

    Marco Dell'Oca

     

    domenica 5 maggio 2019 14:13
  • da quello che hai scritto mi sfugge un concetto.

    per gli utenti che accedono tramite Ms Access le credenziali sono logins di sql server o sono credenziali memorizzate in tabelle di access ?


    Edoardo Benussi
    Microsoft MVP - Cloud and Datacenter Management
    e[dot]benussi[at]outlook[dot]it

    lunedì 6 maggio 2019 07:13
    Moderatore
  • Edoardo buongiorno,

    le credenziali sono solo login di SQL Server con autenticazione windows e sql server.

    Facendo delle prove ho scoperto che le connessioni OLEDB restituiscono il corretto nome dell'utente, mentre le connessioni ODBC restituiscono il solo nome dell'autenticazione windows e non l'autenticazione sql server.

    Nel mio programma utilizzo le autenticazioni ODBC  nelle query passthrough e nelle connessioni tabledef.

    A meno che non ci sia un modo diverso per eseguire le connessioni ODBC ritengo di non poter usare i trigger per inserire il nome utente nei record delle tabelle inserite o modificate.

    Cosa ne pensate? 

    Grazie

    Marco Dell'Oca

    lunedì 6 maggio 2019 10:07
  • Le credenziali sono solo di SQL Server che possono anche essere memorizzate nelle tabelle collegate contenute in ms access.

    In sostanza tutte le tabelle collegate a sql server che si trovano in access hanno memorizzate le stringhe di connessione ad sql server.  Queste sono tutte credenziali di sql server che tramite odbc si collegano al server.

    Spero di essermi spiegato correttamente.

    Marco Dell'Oca

    lunedì 6 maggio 2019 11:44
  • Grazie Igor per la risposta,

    Perchè questa domanda?  <Cosa Intendi?>

    Grazie ancora 

    Marco Dell'Oca

    Quello che volevo capire è se l'ODBC viene configurato e creato sulla macchina client tramite odbcad32.exe o se invece viene usato solo il driver e quindi "ricreata" la stringa di connessione ogni volta.
    Dalla tua risposta direi la seconda.
    Potresti provare ad aprire un profiler su SQL server e vedere nei due casi come si "presenta" l'applicazione e con quali credenziali.
    Aggiungi anche il parametro "Application Name=MyAppName;" alle stringhe di connessione, differenziando ODBC e OLEDb così forse si riesce a vedere come viene fatta la connessione al Db.

    Reference: https://www.connectionstrings.com/use-application-name-sql-server/


    Igor MCSE (once upon a time) -- http://jenga.wordpress.com

    lunedì 6 maggio 2019 14:15
  • Igor buonasera,

    Si, la stringa di connessione viene ricreata tutte le volte che si esegue un login.

    Ho provato ad eseguire un profiler e ho trovato che ms access ha due comportamenti distinti:

    Quando usa OLEDB in connessioni not trasted inserisce il nome dell'applicazione che io ho aggiunto nella stringa di connessione ed usa l'esatto nome dell'utente connesso. Quindi quì tutto bene.

    Quando usa ODBC in connessioni not trasted il nome dell'applicazione è <Microsoft Office> e non il nome applicazione da me inserito ed usa sempre il nome dell'utente windows connesso (nomepc\utentewindows). 

    In conclusione se le odbc di MS Access passano dei parametri identici sia per le connessioni trasted che per le non trasted il trigger di sql server non potrà che restituire tali informazioni.

    Cosa ne pensate?

    Grazie

    Marco Dell'Oca 

    lunedì 6 maggio 2019 16:54
  • mi pare di capire che hai scoperto che in entrambi i casi riesci a ricavare il nome dell'utente connesso perchè utilizzi la sicurezza integrata di windows per autenticare l'accesso alla risorsa e non un account predefinito uguale per tutti.

    è così ?


    Edoardo Benussi
    Microsoft MVP - Cloud and Datacenter Management
    e[dot]benussi[at]outlook[dot]it

    martedì 7 maggio 2019 08:01
    Moderatore
  • Edoardo buongiorno,

    No, esattamente il contrario, il programma usa entrambe le sicurezze sia integrata che non integrata.

    E quando il programma usa la sicurezza non integrata (not trasted) le ODBC passano sempre il nome dell'utente windows connesso (nomepc\utentewindows) e non il nome dell'utente che sta eseguendo il login.

    E' chiaro che c'è un problema, Ms Access invia sicuramente il nome utente e la password di connessione(altrimenti non verrebbe loggato), ma Sql Server nel caso delle ODBC non la considera. 

    Spero di essermi spiegato.

    Grazie 

    Marco Dell'Oca


    martedì 7 maggio 2019 09:22
  • ok, ho bisogno però di capire un'altra cosa: per quale motivo l'accesso da Ms Access verso Sql Server usa due tipi diversi di autenticazione e cosa discrimina un tipo di autenticazione dall'altro ?

    Edoardo Benussi
    Microsoft MVP - Cloud and Datacenter Management
    e[dot]benussi[at]outlook[dot]it

    martedì 7 maggio 2019 10:54
    Moderatore
  • Per motivi di sicurezza, quando su un pc lo stesso utente windows è utilizzato da più utenti.

    Per motivi pratici, in una rete peer to peer dove non c'è un dominio, e un utente utilizza il suo account da più pc.

    Per esplicita richiesta dell'utente.

    E da ultimo perché no visto che esiste l'autenticazione SQL Server.

    Grazie

    Marco Dell'Oca


    martedì 7 maggio 2019 11:30
  • non ho ancora capito come fa un utente ad usare un tipo di autenticazione rispetto all'altra. oppure non è l'utente a compiere questa scelta ?

    Edoardo Benussi
    Microsoft MVP - Cloud and Datacenter Management
    e[dot]benussi[at]outlook[dot]it

    lunedì 13 maggio 2019 09:06
    Moderatore
  • Edoardo buongiorno,

    è l'utente che fa la scelta, il programma è multiserver, multiazienda, multiutente, quindi l'utente sceglie il server e l'istanza, sceglie l'azienda, e da ultimo sceglie la modalità trasted o not trasted.

    questa è la maschera di login.

     

    Marco Dell'Oca

    martedì 14 maggio 2019 09:27
  • la tua applicazione in cosa è scritta ?

    Edoardo Benussi
    Microsoft MVP - Cloud and Datacenter Management
    e[dot]benussi[at]outlook[dot]it

    mercoledì 15 maggio 2019 13:04
    Moderatore
  • In VBA con MS Access.

    Per ciò che access non riesce a fare uso C#.

    Marco Dell'Oca

    mercoledì 15 maggio 2019 15:42
  • In VBA con MS Access.

    Per ciò che access non riesce a fare uso C#.

    Marco Dell'Oca

    a questo punto il consiglio è quello di non far catturare le credenziali di autenticazione da un trigger bensì quello di farle scrivere direttamente nel record dal tuo codice VBA o C# che sia.

    Edoardo Benussi
    Microsoft MVP - Cloud and Datacenter Management
    e[dot]benussi[at]outlook[dot]it

    lunedì 20 maggio 2019 07:03
    Moderatore
  • Be certo Edoardo,

    ma vuoi mettere la differenza, inserire in ogni aggiornamento, in ogni nuovo inserimento un campo con la data ed il nome dell'utente.

    Non c'è modo di suggerire al team che gestisce le ODBC di SQL Server di fare una correzione?

    Anche perché con le OLEDB il problema non c'è.

    Grazie comunque.

    Marco Dell'Oca

    lunedì 20 maggio 2019 09:13
  • io ti ho dato questo suggerimento perchè anch'io sono stato costretto ad adottare questa soluzione in alcune mie applicazioni perchè ritengo che quello che conta sia raggiungere il risultato che serve.

    buon lavoro


    Edoardo Benussi
    Microsoft MVP - Cloud and Datacenter Management
    e[dot]benussi[at]outlook[dot]it

    • Contrassegnato come risposta Marco Dell'Oca sabato 1 giugno 2019 17:58
    lunedì 27 maggio 2019 07:01
    Moderatore
  • In effetti dover creare passi di programma in più per ogni inserimento e modifica in tutto il mio gestionale mi sembra una cosa assurda.

    Anche perché sto trasferendo il backend da Sql Server a  Azure Sql Server (con successo).

    Ho pensato di usare la stringa di connessione inserendo il nome utente nel campo 

    "Application Name=MyAppName_nomeutente;"

    Forse si può recuperare nel trigger il nome utente con qualche stratagemma?

    In effetti il campo program_name della funzione sys.dm_exec_sessions, mi restituisce il nome del programma che esegue il comando insert update, e se in sede di collegamento nel campo program_name aggiungo anche il nome utente lo posso recuperare.

    L'unico problema è come renderlo disponibile nel trigger.

    saluti

    Marco Dell'Oca

     



    lunedì 27 maggio 2019 16:31