2

データベースへのすべての変更をログに記録しようとしていますが、トリガーへの現在のユーザー名を取得する方法を見つけることができませんでした。ユーザーがサインインするときに挿入されるtriggerDataユーザーの情報を格納するテーブルがあります 。(guid (userid), data (username), logintime)

これがトリガーです

declare @UserIsOnlineTimeWindow DateTime
    declare @currenttime DateTime
    set @currenttime = GETDATE()
    set @UserIsOnlineTimeWindow = 10

    DECLARE @uname nvarchar(max)
    **set @uname = (SELECT T.UserName from (SELECT distinct u.UserName FROM aspnet_Users u
    WHERE IsAnonymous = 'FALSE' AND ((@currenttime - @UserIsOnlineTimeWindow) < u.LastActivityDate)) as t,
    TriggerData td, aspnet_Users au 
    WHERE t.UserName = td.Data and td.guid = au.UserId and td.logintime = (select MAX(td.logintime) from TriggerData td))**

    DECLARE @ComputerName nvarchar(50)
    DECLARE @IPAddr nvarchar(50)
    DECLARE @BroadcastIP nvarchar(50)
    DECLARE @auditInsert nvarchar(255)
    SET @ComputerName = (SELECT ComputerName FROM inserted)
    SET @IPAddr = (SELECT ISNULL(IPAddr,0) FROM inserted)
    SET @BroadcastIP = (SELECT ISNULL(BroadcastIP,0) FROM inserted)
    SET @auditInsert =  @ComputerName+' '+@IPAddr+' '+@BroadcastIP
    Begin

    INSERT INTO Audit(OldInfo ,NewInfo,[User],Date1,Type,TableName) VALUES('New Record',@auditInsert, @uname ,GETDATE(),'Added','LabIP')

    End

ユーザー名のクエリは、現在変更中のユーザーを提供するのではなく、最近ログインしたユーザーを提供します。どんな助けでも大歓迎です。ありがとう!

4

1 に答える 1

3

marc_sのように、トリガーはバッチごとに1回適用でき、適用されます。ただし、あなたの場合、現在のアプリケーションはバッチごとに1回しか挿入していないように思われるため、正常に機能しています。ただし、誰かが複数の行を挿入しようとすると、問題が発生します。アプリケーションの別の部分から、またはクエリウィンドウから言います。今すぐ修正するか、破損するのを待つかは、本当にあなた次第です(もしあれば)。

問題が発生しているクエリを再フォーマットしました。

set @uname = (SELECT T.UserName FROM
        (SELECT DISTINCT u.UserName 
        FROM aspnet_Users u
        WHERE IsAnonymous = 'FALSE' 
          AND ((@currenttime - @UserIsOnlineTimeWindow) < u.LastActivityDate)) AS t
        JOIN TriggerData td
          ON t.UserName = td.Data 
        JOIN aspnet_Users au 
          ON td.guid = au.UserId 
        WHERE td.logintime = (select MAX(td.logintime) from TriggerData td))

これから、問題がどこにあるかがわかります。WHERE句を見ると、最後にログインした行を具体的にプルしていることがわかります。アプリケーションIDを使用していない場合は(実際のように聞こえますが)、USER_NAME()またはSUSER_SNAME()を使用してプルできます。現在のユーザー。残念ながら、提供された情報に基づいて、アプリケーションIDを使用していると仮定すると、実際に変更を加えたユーザーをプルすることはできないと思います。

SPID(現在の接続のID)をusersテーブルに入れてみてください。これは@@SPIDとして取得できます。そうすれば、現在の接続にいる間、現在のユーザーが誰であるかを常に知ることができます。もちろん、これは、ユーザーがログインしている間ずっと接続を保持している場合にのみ機能します(おそらくWebベースのアプリケーションでは機能しません)。

最後に(そして残念ながら少なくとも)、トリガーを使用するのではなく、挿入を行うためのストアドプロシージャを作成します。現在のユーザーをパラメータリストの一部としてSPに渡し、そこでロギングを行います。

申し訳ありませんが、これ以上お役に立てませんでした。

于 2013-02-12T23:13:53.410 に答える