如何使用pass through query在if语句中调用存储过程?

时间:2017-02-21 19:22:11

标签: sql vba ms-access stored-procedures pass-through

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

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

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

MS Access 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

3 个答案:

答案 0 :(得分:3)

从根本上说,你没有.Execute你的查询,所以它什么都不做。您只需更改其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

答案 1 :(得分:2)

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

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

更清楚地说明:

  • 用户在frm.UserID
  • 中输入@123
  • 代码连接strFilter& [sp name]& @123
  • IF语句查看frm.UserID的第一个字符,确定它是@,并继续进入代码的True部分
  • true部分将@123作为参数传递给存储过程
  • 存储过程需要一个整数,所以它在获取字符串时会安静地barfs,不会返回任何错误迹象

修复它:

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

这将在将其作为int传递之前修剪UserID 中的前导@

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

答案 2 :(得分: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正在等待一些返回值,但访问没有返回任何东西。