【问题标题】:VB6 Recordset updateVB6 记录集更新
【发布时间】:2012-01-05 17:59:25
【问题描述】:

我正在运行一个 vb6 程序,该程序循环遍历数据库表中的许多记录并将日期输入到字段中。这将需要几个小时才能运行。

我注意到表中的记录数每隔几秒就增加 1,然后减少 1(回到原始计数)。这是有原因的吗?

我正在使用 VB6 记录集和更新功能,即 rs.update。我没有插入任何新记录。

代码如下:

rs.Open "select reference,value1,datefield from datetable where field1 = 'value1' " & _
    "order by reference", objAuditCon.ActiveCon, adOpenStatic, adLockPessimistic

Do While Not rs.EOF
    intReadCount = intReadCount + 1
    DoEvents
    If Not IsNull(rs("value1")) Then
        testArray = Split(rs("value1"), ",")
        rs2.Open "SELECT Date FROM TBL_TestTable WHERE Record_URN = '" & testArray(1) & "'", objSystemCon.ActiveCon, adOpenStatic, adLockReadOnly
        If rs2.EOF Then

        End If
        If Not rs2.EOF Then
            rs("DateField") = Format$(rs2("Date"), "dd mmm yy h:mm:ss")
            rs.Update
            intWriteCount = intWriteCount + 1
        End If
    rs2.Close
    Else    
    End If

rs.MoveNext
Loop
rs.Close

【问题讨论】:

  • 我看不出记录数增加的原因,但只是好奇,您为什么不执行 SQL 语句来更新信息而不是循环遍历记录?然后你可以一次更新一堆。
  • 为什么不创建一个存储过程,然后通过代码执行呢?这应该会稍微缩短您的处理时间。
  • 我在想可能有一个额外的行用于缓存目的?
  • 您如何确定记录数正在发生变化?
  • CraigJ,我只是在 SQL Studio 管理器中运行计数,即从日期表中选择计数(*)?每秒按一下执行按钮,计数偶尔会增加一条记录,然后立即减少一条记录?你有什么想法?谢谢。

标签: vb6 ado recordset


【解决方案1】:

你可以在这里大大减少你的 SQL 工作。

If Not IsNull(rs("value1")) Then
        testArray = Split(rs("value1"), ",")
        rs2.Open "SELECT Date FROM TBL_TestTable WHERE Record_URN = '" & testArray(1) & "'", objSystemCon.ActiveCon, adOpenStatic, adLockReadOnly
        If rs2.EOF Then

        End If
        If Not rs2.EOF Then
            rs("DateField") = Format$(rs2("Date"), "dd mmm yy h:mm:ss")
            rs.Update
            intWriteCount = intWriteCount + 1
        End If
rs2.Close

实际上,在我看来(我已经 10 年没有使用过 VB6 和 ADO),加载您的记录初始记录集,检查一个值,如果该值不为空,则运行第二个选择 THEN 更新记录集.... 您可以创建一个命令对象而不是执行所有这些操作 在你的循环之前声明这些 dim objComm set objComm = Server.CreateObject("ADODB.Command")

objComm.ActiveConnection =  objSystemCon.ActiveCon 'I think this is your connn.
objComm.CommandType = 1 'adCmdText

在你的循环中使用它

objComm.CommandText = "UPDATE DateTable SET DateField = (SELECT Date FROM TBL_TestTable WHERE Record_URN = '" & testArray(1) & "'")
objComm.Execute 

与其进行第二次谨慎选择,将数据拉入,然后进行更新并将其推出,只需推出更新语句即可。这应该会加快您记录的处理速度.....我知道我很久以前就用 VB6 写过这样的东西:)

所以你的代码现在应该是这样的

dim objComm
set objComm = Server.CreateObject("ADODB.Command")` 

    objComm.ActiveConnection =  objSystemCon.ActiveCon 'I think this is your connn.
    objComm.CommandType = 1 'adCmdText

rs.Open "select reference,value1,datefield from datetable where field1 = 'value1' " & _
    "order by reference", objAuditCon.ActiveCon, adOpenStatic, adLockPessimistic

Do While Not rs.EOF
    intReadCount = intReadCount + 1
    DoEvents
    If Not IsNull(rs("value1")) Then
        testArray = Split(rs("value1"), ",")
    objComm.CommandText = "UPDATE DateTable SET DateField = (SELECT Date FROM TBL_TestTable WHERE Record_URN = '" & testArray(1) & "'")
    objComm.Execute 

    End If

rs.MoveNext
Loop
rs.Close

如您所见,您的 select 语句仍然存在,它现在是一个子选择,优点是巨大的,您无需将记录绘制到服务器,然后更新它们。您正在向服务器发送执行更新的语句。您的行程减少了一半。

希望这是有道理的。

【讨论】:

  • 乔丹,我意识到有更好的方法来编写代码。但是,最初的问题专门询问为什么记录数每隔几秒钟就增加 1 条记录,然后立即减少 1 条记录。我通过在 SQL Studio Manager 中运行 SQL 查询来建立记录计数。谢谢。
  • 是的,我意识到很抱歉,只是不得不借此机会提出建议。一定是有别的原因造成的。表上有索引吗?也许不断的更新导致索引返回一些稍微不同的值。我怀疑没有创建额外的行。如果你真的相信有一个额外的行,我想你可以将表复制到另一个包含所有数据的表并运行查询以提取处理表上存在的那些与静态备份副本。这会很慢,我认为它不会显示任何内容。
  • 谢谢乔丹。我整天都在想这个。我已经对数据进行了一些测试,尽管它在程序运行时返回了更多行;当我尝试运行比较时,它不会返回任何行,即从 datetable 中选择 *,其中没有引用(从 datetabletest 中选择引用)。表 datetabletest 是在我运行程序之前创建的。当我添加主键时,问题不再存在,即计数是一致的。您还有其他想法吗?
  • 今天早上我无法访问此主题,但它似乎又出现了。
  • 一个主键会为表添加一个聚集索引。也许你以前没有索引?我想某些行锁定可能会导致行数不同。拥有一个索引将允许它访问行计数,而不管表级锁如何。我知道挂起的交易可能会给出不正确的行数,所以我想这是可能的。如果您熟悉 ACID I is Isolation,那么服务器可能在实际更新时并未处理该行。现在我想到了一个更新有一个可能会阻止读者的隐式事务。
【解决方案2】:

简单的答案:去掉 DoEvents 语句。如果您使用它来刷新屏幕,则在循环 1000 次迭代后定期手动刷新您的 GUI。

这可能导致问题的原因是,当您调用 DoEvents 时,可能正在执行您可能无法控制的其他代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多