Sql server 如何从SQL后端审核表中的MS Access前端MDW获取用户名?

Sql server 如何从SQL后端审核表中的MS Access前端MDW获取用户名?,sql-server,ms-access,Sql Server,Ms Access,我有一个连接到SQL server后端的MS Access 2003 mdb和mdw。这些表使用系统DSN链接。我在SQL后端表上有一个触发器,它在insert、update和delete时将一条记录插入另一个后端审计表。这一切都很好,但是触发器使用system_user来获取进行记录更改的人,而表只是记录DSN在链接访问表中进行更改时要使用的用户名。如果DSN设置为使用通用sql用户名“foo”,而MDW使用的是特定于用户的名称“bar”,则后端的审核表(如果将所有用户的所有更改记录为用户“f

我有一个连接到SQL server后端的MS Access 2003 mdb和mdw。这些表使用系统DSN链接。我在SQL后端表上有一个触发器,它在insert、update和delete时将一条记录插入另一个后端审计表。这一切都很好,但是触发器使用system_user来获取进行记录更改的人,而表只是记录DSN在链接访问表中进行更改时要使用的用户名。如果DSN设置为使用通用sql用户名“foo”,而MDW使用的是特定于用户的名称“bar”,则后端的审核表(如果将所有用户的所有更改记录为用户“foo”)。用户使用mdw文件登录到mdb,我想在SQL后端记录来自mdw的用户名。这可能吗?

在Access VBA中,您可以使用CurrentUser()函数返回MDW用户名。您需要找到一种方法将该名称告知SQL Server。如果要从Access生成并提交DML语句,可以将CurrentUser值添加为字段表达式

我对Access用户级安全性和SQL Server身份验证都很好奇。乍一看,这听起来像是一个“皮带和吊带”的方法。。。除了SQL Server可能是一条非常有效的安全带,而Access用户级安全性是一组相对无效的吊杆。我想知道ULS为您的申请增加了什么好处


考虑放弃ULS并切换到SQL server的Windows身份验证。这可能是一种更简单、更干净、更安全的方法

我打赌@spid在触发器中起作用,因为它是由执行DML的进程执行的

请注意,这可能并不总是可靠的,因为有时Access会打开额外的连接,而没有任何方式运行您的特殊代码来根据正在使用的spid记录用户

更新

您是否考虑过使用特定于每个SQL Server会话的CONTEXT_INFO变量

DECLARE @Info varbinary(30)
SET @Info = Convert(varbinary(30), 'My Username')
SET CONTEXT_INFO @Info
SELECT Left(Convert(varchar(30), CONTEXT_INFO()), CharIndex(0x0, CONTEXT_INFO()) - 1)

这可能意味着不管怎样,都要在幕后点击一个表,但这肯定比自己动手要快。

他可能需要保护访问对象:表单、报表等,而不仅仅是数据。我想的是,我可以将主机名和currentuser()放在一个用SQL链接的临时表中。我使用的是SQL 2008,因此如果我查看sys.sysprocesss,我可以找到SPID和主机名,其中程序名为“Microsoft Office 2003”。如果我能找到执行insert/update/delete触发器的进程的SPID,那么我可以尝试将主机名绑定到SPID,并通过temp表返回到访问用户名。我只是不知道如何在触发器中找到执行insert/update/delete的进程的SPID。只需分发MDE,就可以更好地保护前端的访问对象,这使得它们不可编辑。您不太可能需要区分每个用户对Jet用户在前端使用对象的权限。也就是说,你可以很容易地用两个用户在前端设计你的安全性,管理员(对每个人)和另一个用户(可以进行更改的用户)。我绝对同意@HansUp的观点,即在前端使用颗粒喷射ULS可能没有什么好处。即使您继续这样做,为什么不使用Windows登录记录您的审核跟踪?这还不够吗?是的,它需要使用Windows身份验证,但无论如何,这比SQL身份验证容易得多。前端上的表使用系统DSN链接,因此到SQL server,就好像有多个相同用户的实例登录,而实际上有许多不同的用户在不同的机器上使用FE。除此之外,访问安全性还用于在FE内部为操作定义额外级别的自定义权限(例如,只有QA人员才能执行操作x)。是的,一种方法是将所有内容移动到Windows身份验证,但这将是一个很大的改变。感谢您提醒我使用@SPID。我喝了一杯精神玛格丽塔酒。解决方案是在服务器中创建一个表来存储Access中的主机名和用户名。主窗体打开事件将VBA.Environ(“COMPUTERNAME”)和CurrentUser()中的主机名插入此表。在审计触发器中,我在sys.sysprocesss.hostname=dbo.AccessUsers.hostname中找到用户名,其中选择@username=dbo.AccessUsers.username从sys.sysprocesss内部连接dbo.AccessUsers在sys.sysprocesss.hostname=dbo.AccessUsers.hostname中(sys.sysprocesss.program_name='Microsoft Office 2003'),sys.sysprocesss.spid=@@spid这太好了!是否有任何方法可以存储spid而不是实时查找用户名,然后根据spid和日期/时间(使用具有当前用户历史记录的表)将其转换为用户名?你做这件事的方式很好,只是最好在一个触发器中尽可能少地做…我认为这可能会让用户登录和注销变得混乱。你会得到一个大的重复信息表。您必须将时间记录到一个表中,然后触发访问表以在SQL中查找SPID,或者使用ADO在访问端进行插入。我同意让触发器做最少的工作,但我认为从长远来看,让触发器找到用户名会更干净。如果你能想出更好的方法,我洗耳恭听。有一个特殊的变量,你可以存储特定于会话的数据。。。让我试着找到这个。找到了!请参阅更新。