【问题标题】:Values not updating correctly in database after being operated on in a loop循环操作后数据库中的值未正确更新
【发布时间】:2011-03-18 09:34:29
【问题描述】:

我有以下代码:

Imports System.Data
Imports System.Data.OleDb
Partial Class Dummy
Inherits System.Web.UI.Page

Dim r As OleDbDataReader
Dim con As OleDb.OleDbConnection
Dim cmd As OleDbCommand
Dim cmd1 As OleDbCommand
Dim prev_ob As New List(Of Int64)
Dim cur_ob As Integer
Dim i As Integer = 0

Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click

    con = New OleDb.OleDbConnection("provider=SQLOLEDB;data source=PC;initial catalog=DB1;integrated security=SSPI")
    cmd = New OleDbCommand("select single_column from table1 where date_reqd=(SELECT CONVERT(VARCHAR(10),DATEADD(DD, DATEDIFF(DD, 0, GETDATE()), -1),120))", con)
    con.Open()
    r = cmd.ExecuteReader
    While r.Read
        prev_ob.Add(Val(r.Item(0)))
    End While

    cmd = New OleDbCommand("select column1, column2, date_reqd from table1 where date_reqd=(select CONVERT(varchar(10), GETDATE(),120))", con)
    r = cmd.ExecuteReader
    While r.Read
        For i As Integer = 0 To prev_ob.Count - 1
            cur_ob = Val(prev_ob(i)) + Val(r.Item(0))
            cmd1 = New OleDbCommand("update table1 set column4='" & cur_ob & "' where column2='" & r.Item(1) & "' and date_reqd='" & r.Item(2) & "'", con)
            cmd1.ExecuteNonQuery()
            i += 1
            Exit For
        Next
    End While
    con.Close()
End Sub
End Class  

我面临的问题是更新仅针对许多值中的第一个正确发生。所有其他值都是计算出来的,因此在我的表中更新不正确。我几乎可以肯定循环是导致问题的原因,但一直无法找到解决方法。请帮我改正。

【问题讨论】:

  • 你是在不检查任何条件的情况下调用 Exit For 吗?
  • @vs 开发者:你好! :) Exit For 只是我试图使该死的事情起作用的众多变体之一。不幸的是,我删除了所有其他变体,只是粘贴了我所拥有的。我也试过For EachFor Each obj in prev_ob 等等等等。没用。在那种情况下,发生的事情是它用最后一个计算值更新了所有行的值。当我输入MsgBox 时,它显示了正确的值。我去数据库看看,它已经插入了最后一个计算值。 WTF错了吗? :
  • 看起来这应该可以作为单个 UPDATE 语句(column1 和 single_column 是同一列吗?)

标签: vb.net for-loop while-loop sqldatareader sql-update


【解决方案1】:

看起来这应该是一条 UPDATE 语句。不幸的是,如果没有看到您的实际表结构就很难判断。首先,写一个这样的选择语句(我希望 date_reqd 实际上也是一个日期时间列):

SELECT
    *
FROM
    table1 t1a
         inner join
    table1 t1b
         on
             t1a.date_reqd = DATEADD(day,DATEDIFF(day,0,CURRENT_TIMESTAMP),-1) and
             t1b.date_reqd = DATEADD(day,DATEDIFF(day,0,CURRENT_TIMESTAMP),0) and
             /* You need other conditions here if there are multiple rows for the same dates
                - I'm guessing there are since you're trying to write a loop */

一旦您的查询工作正常,请删除前两行 (SELECT *),并将它们替换为:

UPDATE
    t1b
SET
    column4 = t1a.single_column + t1b.column1

你应该完成了。

【讨论】:

  • @Damien_The_Unbeliever:只有一张表包含所有这些数据。而且,single_column 和 column1 是不一样的。 single_column 只是表示我正在检索一个 single_column 并将其插入到一个数组列表中。
  • @Akshay - 是的,我上面的第一个查询只引用了一个表 - 但我引用它两次,这样我就可以加入“上一个”行(通过引用 table1 获得 @987654325 @) 到“当前”行(通过将table1 引用为t1b 获得)。这只是让连接条件正确的问题。而且我基于 single_column 和 column1 不同的假设编写了更新查询。
  • @Akshay - 您当前的查询也没有 ORDER BY 子句,因此无法保证多行将交付给您的顺序 - 如果您可以发布表结构(减少到我们在这里使用的列)、一些示例数据和预期结果,我也许还可以编写一个实际测试过的查询。
  • @Damien_The_Unbeliever:我会试一试。谢谢! :)
  • @Akshay - 如果您不提供 ORDER BY 子句,则允许 SQL Server 按其可用的 任何 顺序返回结果。如果您目前看到特定订单,那完全是由于好运/幸运,而不是您应该依赖的任何东西。
【解决方案2】:

我自己搞定了! :) 我需要做的就是:

Dim i as Integer=0  

While r.Read  
    cur_ob = Val(prev_ob(i)) + Val(r.Item(0))  
    cmd1 = New OleDbCommand("update table1 set column4='" & cur_ob & "' where column2='" & r.Item(1) & "' and date_reqd='" & r.Item(2) & "'", con)  
    cmd1.ExecuteNonQuery()  
    cur_ob = 0  
    i += 1  
End While  

它奏效了!感谢您的回答/cmets 和 @Damien_The_Unbeliever,我更改了主要查询以包含 ORDER BY 子句。谢谢你的提示! :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-28
    • 1970-01-01
    相关资源
    最近更新 更多