我正在研究一个将MS Access后端数据库迁移到SQL Server的项目。现有的MS Access前端需要保留。
为了提高安全性,我正在使用服务帐户将Access前端连接到SQL数据库-以便各个用户无法直接访问SQL。
我希望能够记录UserId的记录中的添加和更新操作,但是我不想在每次调用时都指定字段。
我在Access中打开了一个隐藏表,以维护与SQL数据库的持久连接。我已经在Access启动时使用Sub调用了在Access中使用UserId创建的Session Context对象,并且甚至在运行记录插入之前就直接调用了Sub。
Sub SqlSetUser()
Dim qdef As DAO.QueryDef
Set qdef = CurrentDb.CreateQueryDef("")
qdef.Connect = CurrentDb.TableDefs("dbo_User").Connect
qdef.SQL = "EXEC sys.sp_set_session_context @key = N'UserId', @value = '" & GetUser() & "';"
qdef.ReturnsRecords = False ''avoid 3065 error
qdef.Execute
End Sub
并且我在SQL表中创建了一个触发器以提取UserId并将其添加到要添加的记录中,并使用类似的触发器来处理更新;
CREATE TRIGGER [dbo].[ReferenceItemAdd]
on [dbo].[ReferenceItem]
FOR INSERT
AS
BEGIN
SET NOCOUNT ON;
declare @UserId as int = try_cast((Select SESSION_CONTEXT(N'UserId')) as int)
UPDATE ReferenceItem set AddDate = getdate(), AddUserId = @UserId
from INSERTED i, ReferenceItem a
where i.ReferenceItemId = a.ReferenceItemId
SET NOCOUNT OFF;
END
我的问题是它[[似乎只有在我通过断点停止代码然后继续时才起作用,如果我只允许代码运行,则将记录插入ok,并且触发器正确设置了AddDate,但UserId返回NULL。
[有没有人有类似的经历,或者有没有人有方法可以从MS-Access前端访问UserId以用于MS-SQL中的触发器?干杯,菲尔。
如果您有一个客户端Web浏览器和一个Web服务器,那么您肯定有一个可以使用服务帐户更新SQL数据库的Web服务器,因为您在客户端和SQL数据库之间有一个WHOLE Web服务器。
您没有上述任何一项。
例如:
qdef.Connect = CurrentDb.TableDefs("dbo_User").Connect
qdef.SQL = "EXEC
正确,因此您已链接了表,并且上面是一个连接字符串,它直接访问数据库,甚至能够执行存储过程。我假设此连接是链接表使用的相同连接吗? (无论如何,我们可以将假定的安全问题再搁一整–您这里拥有的是jane链接表,它们可以直接更新数据库,甚至可以按照上述示例执行存储过程代码。下一个:
我们假设这里使用了一个SQL登录?
您的代码应该可以工作,这看起来是错误的:
declare @UserId as int = try_cast((Select SESSION_CONTEXT(N'UserId')) as int)
为什么将上面的内容转换为整数?不是您设置字符串的GetUser()吗? (您的示例代码的文字周围为“”-因此假定为字符类型。这是直接变量分配-您不需要选择。
您应该使用:
DECLARE @UserID as varchar(25) = CAST(SESSION_CONTEXT(N'UserId') AS varchar(25))
我不知道所有链接表的会话是否保持不变。我会100%确保所有链接表都具有完全相同的连接字符串。您应该能够在启动时执行一次代码来设置该会话值。但是,我不是100%肯定会一直在这里使用单个会话(您可以回来确认这一点-因为我很感兴趣,如果是这种情况)。