如何在“更新触发器”中存储正在更新表值的UserName?

时间:2013-11-11 08:06:01

标签: sql sql-server triggers sql-server-2012

在我的网络应用程序中,我正在创建一个日志过程。我创建了一个更新触发器,它工作得很好,但我需要知道谁更新了这些数据,即执行此操作的用户。

我用google搜索并要求使用context_info。这是什么意思?

如何在触发表中存储此信息?

这是我的程序..我用过你的概念..

ALTER Procedure [dbo].[MIS_CompOffDate]   
(  
@EmpId nvarchar(20), 

@UserName nvarchar(50),

@ActualDate datetime,

@DayName nvarchar(20),

@CompOffDate datetime 

)  

As

Begin 

DECLARE @UserNameConverted VARBINARY(128) = CONVERT(VARBINARY(128), @EmpId);

SET CONTEXT_INFO @UserNameConverted;  

INSERT INTO MIS_BM_CompOff values(@EmpId, @UserName, @ActualDate, @DayName, @CompOffDate)

End

在empid中 - 用户的empid就在那里......

4 个答案:

答案 0 :(得分:2)

我遇到了同样的问题,并在SO上使用了一些答案来解决这个问题。我创建了一个存储过程sp_SetConnectionUsername来保存用户名,还有一个函数f_GetConnectionUsername可以在触发器中用来检索用户名。因为CONTEXT_INFO以二进制形式存储数据,所以需要进行一些调整以使varchar数据退出。请注意,CONTEXT_INFO的限制是128个字节(所以128个字符)。

以下是从应用程序打开连接以设置用户名时调用的存储过程:

CREATE PROCEDURE [dbo].[sp_SetConnectionUsername]
    @username varchar(128)
AS
BEGIN
    -- Convert username varchar into binary
    DECLARE @binaryUsername varbinary(128)
    SET @binaryUsername = CAST(@username as varbinary(128))
    SET CONTEXT_INFO @binaryUsername
END

这是在触发器中调用以检索用户名的函数:

CREATE FUNCTION [dbo].[f_GetConnectionUsername]()
RETURNS varchar(128)
AS
BEGIN
    DECLARE @username varchar(128)

    -- Get binary from CONTEXT_INFO, convert to varchar, then remove all Char(0) 
    -- empty characters from it (these are used as spacing in binary). Otherwise,
    -- if CONTEXT_INFO has not been set, return the SQL Server username.
    IF CONTEXT_INFO() IS NOT NULL
        SET @username = REPLACE((select cast(CONTEXT_INFO() as varchar(128))) COLLATE 
            Latin1_General_BIN, CHAR(0), '')
    ELSE
        SET @username = SYSTEM_USER

    RETURN @username
END

希望可以帮助别人。

答案 1 :(得分:1)

您可以使用触发器将SYSTEM_USERUSER_NAME()插入表格中。 因此,触发触发器的任何操作都将具有该人员的登录名或用户名。 这是在数据库内部。但对于Web应用程序,您可以保存代理人的登录名信息,在任何成功登录后的变量中以及任何更新中使用存储过程,其中一个请求的参数应该是该登录参数。

答案 2 :(得分:0)

触发器只会知道您对表所做的更改,它不会知道实际插入/更新外部的信息等。

最好从您的应用程序处理它,并将有关更新用户的信息与其他信息一起传递。

答案 3 :(得分:0)

可以按照以下步骤进行:

  1. 将更新功能/程序传递给用户ID或名称
  2. 在更新功能/过程中,将用户ID或名称设置为共享 使用SET CONTEXT_INFO这样的变量:

    SET CONTEXT_INFO @UserID
    
  3. 在触发器中,使用CONTEXT_INFO()函数提取ID:

    DECLARE @UserID BIGINT = COALESCE(CAST(CAST(CONTEXT_INFO() AS BINARY(8)) AS INT),0)