1

我正在为我的应用程序使用 MS Access VBA 和 SQL Server 存储过程。我有一个表单frmUsers,它有一个文本框UserName。它绑定到 tblUsers 的用户名。如果用户在文本框输入值前使用“@”更新它,则必须清除SQL 表中的某些列(Password和) 。HashtblUser

我已经为它创建了一个存储过程,并且还在UserName_AfterUpdate下编写了一些代码。我觉得我需要创建一个传递查询来调用If语句中的存储过程,如下所示;但它不起作用(没有删除表中的值,也没有给出任何错误)。

存储过程本身可以工作,但是当我尝试使用应用程序测试它时,即在文本框前面插入'@',它不会删除表中的两列。我错过了在传递查询和文本框之间绑定的东西。请帮忙。

微软访问VBA

Private Sub UserName_AfterUpdate()
    On Error Resume Next
    Dim frm As Form
    Dim strFilter As String

    Dim DB As Database
    Set DB = CodeDb

    DoCmd.OpenForm "frmUsers", , , , , acDialog
    Set frm = Forms!frmUsers

    If frm.Tag Then
        strFilter = strFilter & "sp_ClearWebsitePwd"
        strFilter = strFilter & ", " & frm!UserID      

        If Left(UserName, 1) = "@" Then        

            DB.QueryDefs("qryClearWebsitePwd").Connect = SQLConnectString
            DB.QueryDefs("qryClearWebsitePwd").sql = strFilter
        End If  
    End If
End Sub

SQL Server存储过程

CREATE PROCEDURE [dbo].[sp_ClearWebsitePwd] 
    @userID INT
AS
BEGIN
    SET NOCOUNT ON; 

    UPDATE tblUser
    SET tblUser.Password = NULL, tblUser.Hash = NULL
    WHERE UserID = @userID 
END         

MS Access 直通查询(qryClearWebsitePwd)

sp_ClearWebsitePwd, 20226
4

3 回答 3

3

从根本上说,您不会。执行您的查询,因此它什么也不做。您只需更改其 SQL 和连接字符串属性。

此外,调用存储过程时不需要逗号分隔或“@”前缀。从表单中删除“@”用户指令并传递整数。如果连接属性永远不会改变,则无需更新它,因此可以删除该行。

If frm.Tag Then
    strFilter = "sp_ClearWebsitePwd " & frm!UserID      

    DB.QueryDefs("qryClearWebsitePwd").Connect = SQLConnectString
    DB.QueryDefs("qryClearWebsitePwd").SQL = strFilter
    DB.QueryDefs("qryClearWebsitePwd").Execute dbFailOnError
End If
于 2017-02-21T21:10:43.353 回答
2

谢谢大家试图帮助我。我发现我错过了什么。一切都是正确的,除了我错过了设置DB.QueryDefs("qryClearWebsitePwd").ReturnsRecords = False 所以,正确的版本将是:

Private Sub UserName_AfterUpdate()
    On Error Resume Next
    Dim frm As Form
    Dim strFilter As String

    Dim DB As Database
    Set DB = CodeDb

    DoCmd.OpenForm "frmUsers", , , , , acDialog
    Set frm = Forms!frmUsers

    If frm.Tag Then
        strFilter = strFilter & "sp_ClearWebsitePwd"
        strFilter = strFilter & ", " & frm!UserID      

        If Left(UserName, 1) = "@" Then        

            DB.QueryDefs("qryClearWebsitePwd").Connect = SQLConnectString
            DB.QueryDefs("qryClearWebsitePwd").ReturnsRecords = False
            DB.QueryDefs("qryClearWebsitePwd").sql = strFilter
            DB.QueryDefs("qryClearWebsitePwd").Execute dbFailOnError
        End If  
    End If
End Sub

一旦我添加了这行代码,它就可以正常工作了。似乎 SQL 正在等待一些返回值,但访问没有返回任何内容。

于 2017-02-24T14:55:27.097 回答
2

因为“@”不是整数,但你的参数是

CREATE PROCEDURE [dbo].[sp_ClearWebsitePwd] 
  @userID INT
AS

为了更清楚:

  • 用户输入@123frm.UserID
  • 代码连接strFilter& [sp 名称] &@123
  • IF语句查看 frm.UserID 的第一个字符,确定它是一个@,然后继续进入True代码部分
  • true 部分@123作为参数传递给存储过程
  • 存储过程需要一个整数,所以当它得到一个字符串时它会安静地发出声音,不返回任何错误指示

要解决这个问题:

If frm.Tag Then
    If Left(CustomerName, 1) = "@" Then        
        strFilter = strFilter & "sp_ClearWebsitePwd" 
        strFilter = strFilter & ", " & right(frm!UserID, len(frm!UserID) - 1)

        DB.QueryDefs("qryClearWebsitePwd").Connect = SQLConnectString
        DB.QueryDefs("qryClearWebsitePwd").sql = strFilter
    End If  
End If
'assumes something happens here to actually execute the query

@这将在将 UserID作为 int 传递之前修剪前导。

老实说,我建议您尝试找到另一个触发值来指示帐户已被禁用。也许考虑添加一个“活动”字段(将所有人设置为 True)并使用您的 SP 将其设置为 False,或者相反,添加一个“禁用”字段(将所有人设置为 False)并使用您的 SP 将该字段设置为“真的'。

于 2017-02-21T20:29:42.540 回答