【问题标题】:MS Access 2010: VBA code runs multiple timesMS Access 2010:VBA 代码运行多次
【发布时间】:2017-12-16 13:23:35
【问题描述】:

我遇到了一个以前从未遇到过的问题,我看不到任何错误。

表单上有一个按钮cmdCreateOrder,它运行对 SQL Server 的传递查询并执行存储过程,此查询将值返回给 Access。

按钮cmdCreateOrder:

Private Sub cmdCreateOrder_Click()
Dim strsql As String
Dim intNumberProducts As Integer

If MsgBox("Want to create an order?" & vbCrLf & vbCrLf _
        & "Click 'Yes' to create", vbQuestion + vbYesNo, "Question") = vbNo Then
        Exit Sub
End If

    strsql = "exec dbo.spCreateOrder 'CreateOrdersKd', 1, " & Me.OfferID & ", " & Me.KdID & ", " & TempVars!intUser
    Debug.Print strsql
    Call SQL_PT(strsql, "PT_LookupWerte")

    intNumberProducts = DLookup("NumberProducts", "PT_LookupWerte")

    Me.Bestelldatum = Date
end Sub

函数SQL_PT:

Function SQL_PT(ByVal SQL As String, Optional QueryName As String)  
Dim qdf As QueryDef

On Error GoTo ErrHandler

'if no query name then create temp qry
If Len(QueryName) = 0 Then 'temp Abfrage

    Set qdf = CurrentDb.CreateQueryDef("")
    With qdf
        .Connect = TempVars!ConnectionString
        .SQL = SQL
        .ReturnsRecords = False  'Wenn kein QueryName angeliefert wird, dann ergibt .ReturnsRecords = 0 und die Abfrage wird einfach ausgeführt
        .Execute
    End With

Else  'if a qry name provided, then run qry which returns values
    Set qdf = CurrentDb.QueryDefs(QueryName)
    qdf.SQL = SQL
End If

qdf.Close
Set qdf = Nothing

ExitHere:
    Exit Function

ErrHandler:
    Resume ExitHere
End Function

我在这个项目中使用了很多这样的代码,它们都可以正常工作。但是这个按钮点击至少运行了 3 次EXEC 并创建了 3 个(或更多)订单。

访问 VBA 调试测试

更奇怪的是,我在即时窗口中只得到了一行。 当我在 PT 查询 (PT_LookupWerte) 中使用 Debug.Print 结果(例如 exec dbo.spCreateOrder 'CreateOrdersKd', 1, 8, 2001, 1)时,只需 ONE 顺序即可正常工作。

SQL Server 存储过程测试

当我在 SQL Server 上运行存储过程时:exec dbo.spCreateOrder 'CreateOrdersKd', 1, 8, 2001, 1 它也只创建了一个订单并且它运行正常。

只有在 Access 中单击按钮时才会运行多次。

我对数据库进行了压缩、修复和反编译。现在我不知道问题出在哪里了。

有什么想法吗?

【问题讨论】:

  • SQL_PT 后面的代码是什么?也可能不相关,但 DLookup("NumberProducts", "PT_LookupWerte") 不应该有一些标准作为第三个参数吗?
  • 我在问题中添加了函数 SQL_PT。
  • 创建 3 个(或更多)订单 ...这里在哪里创建订单?你怎么知道它运行了 3 次?
  • @Parfait:因为我通过存储过程 exec dbo.spCreateOrder 'CreateOrdersKd' 获得了 3 个新订单...如果我在服务器上运行相同的 sp 或使用该 SQL 语句执行 PT 查询访问,结果正确!!!这就是为什么我找不到它的解释。当我没有在函数中添加任何 PT_query 的名称(例如“PT_LookupWerte”)时也是正确的,它应该从 sp 中检索值。正如我所说,我以前在许多数据库中从未有过这种经验。使用 fnc SQL_PT 我还从任何 sp 检索报告的数据,这是正确的。那么有什么问题呢??
  • 原谅我,但你没有完全回答我的问题。告诉您创建了 3 个订单的具体输出是什么?例如不是 1 个甚至 100 个订单?其实什么是orders?访问报告?您的所有代码显示都是DLookUp 调用?单击按钮时是否会发生其他情况?

标签: sql-server vba ms-access stored-procedures


【解决方案1】:

使用 DAO 执行存储过程(就像您的 SQL_PT 一样)是一个糟糕的计划。

将存储过程存储在 QueryDefs 中并使用 DLookUp 而不是 .Execute 或 .OpenRecordset 执行它们是一个糟糕的计划。

一个简单的解决方法是将intNumberProducts = DLookup("NumberProducts", "PT_LookupWerte") 替换为intNumberProducts = CurrentDb.QueryDefs("PT_LookupWerte").OpenRecordset.Fields("NumberProducts").Value

更好的解决方法是将存储过程代码移至 ADO,并使用命令对象和参数来执行存储过程。

【讨论】:

  • Erik,例如,我以同样的方式检查了这个应用程序的登录数据,它可以工作。多年来,我在许多数据库中都使用这种方法来检索数据。我将删除所有的 querydefs 并为新的创建它们,可能出于任何原因它们已损坏。
  • 不,使用DLookUp 的技术只是有缺陷。对于检索数据,它只是效率低下,但对于更新数据,它可能会导致错误。你应该调整它。
  • 好的,我尝试使用记录源解决方案来确定问题是否消失。谢谢
  • 更正:记录集,而不是记录源!
  • Erik,非常感谢,它适用于您的解决方案!我不知道,Dlookup(或者很可能是所有域功能??)对服务器功能有这样的影响!
猜你喜欢
  • 2018-06-24
  • 1970-01-01
  • 2017-08-17
  • 2015-06-24
  • 1970-01-01
  • 1970-01-01
  • 2012-03-03
  • 1970-01-01
  • 2013-05-17
相关资源
最近更新 更多