【问题标题】:SQL data reader only reads the first row in VB.netSQL 数据读取器只读取 VB.net 中的第一行
【发布时间】:2018-06-16 02:33:31
【问题描述】:

我有一个数据库,其中包含一个名为restaurant 的表。该表有名为“time”和“tableno”的列,有 20 行。 我正在使用此代码读取数据:

    Dim connString As String = "server=DESKTOP-69QA9LH\SQLEXPRESS; database=servicedb; integrated security=true"
    Dim conn As New SqlConnection(connString)
    Dim command As SqlCommand
    Dim reader As SqlDataReader

    conn.Open()
    Dim query As String
    query = "select time,tableno from restaurant "
    command = New SqlCommand(query, conn)
    reader = command.ExecuteReader
    reader.Read()
    Dim d1 As DateTime = ToolStripStatusLabel1.Text
    Dim d2 As DateTime = reader("time")
    Dim diff As Short = DateDiff(DateInterval.Minute, d2, d1)

    If reader("tableno") = "2" AndAlso diff = "5" Then
        Button3.BackColor = Color.LawnGreen
    End If

    If reader("tableno") = "2" AndAlso diff = "10" Then
        Button3.BackColor = Color.LawnGreen
    End If       

    If reader("tableno") = "2" AndAlso diff = "15" Then
        Button3.BackColor = Color.LawnGreen
    End If

    If reader("tableno") = "1" AndAlso diff = "5" Then
        Button1.BackColor = Color.Brown
    End If

    If reader("tableno") = "1" AndAlso diff = "10" Then
        Button1.BackColor = Color.Brown
    End If
    If reader("tableno") = "1" AndAlso diff = "15" Then
        Button1.BackColor = Color.Brown
    End If

它几乎可以工作,但问题是它只读取表中的第一行。我的意思是,当我单击按钮处理此代码时,按钮仅根据表格的第一行更改背景颜色。

'tableno' 2 的行是第一行,它改变了背景颜色。但是 'tableno' 1 是第二行,我无法读取这一行来更改背景颜色。

如何使它与其他行一起使用?

【问题讨论】:

  • 您需要花一些时间了解 ADO.NET 的工作原理。你知道你调用的Read 方法实际上是做什么的吗?看来你真的没有。花时间阅读该方法的文档并查看一些示例。 Here 是我自己的。
  • 你能帮我更正我的代码吗?因为我不确定如何将你的代码实现到我的代码中。
  • 原理明白了吗?那就是问题所在。在您的代码中,您调用了一次Read,因此您只读取了一条记录。如果您希望读取每条记录,那么您必须继续调用Read,直到没有更多记录可供读取。你通常如何多次做同样的事情?通过使用循环。我提供的链接演示了如何做到这一点。我不再提供任何内容,因为本网站并非旨在作为基础教程或代码编写服务。
  • 请您查看此网址以提高问题的质量stackoverflow.com/help/how-to-ask

标签: sql-server database vb.net sqldatareader


【解决方案1】:

这里有几点...

  1. SqlConnectionSqlCommandSqlDataReaderIDisposable,所以应该在 using 块中。
  2. 您只处理第一行,因为您没有使用循环遍历所有行。
  3. 只有一个“Button1”和一个“Button3”,因此虽然下面的代码会遍历所有行,但它每次都会更新相同的控件,因此您不会看到任何差异。在不知道您的屏幕是什么样子的情况下,我无法为此提供解决方案。
  4. 您对类型有点模棱两可。例如,“diff”是short;但是您正在将其与字符串进行比较。在此基础上,我将假设 TableNo 列是int。尽量确保将字符串与字符串进行比较,将整数与整数进行比较,等等。
  5. 考虑为您的变量提供正确的名称,而不仅仅是 d1d2
  6. DataReader 具有用于从列中获取值的强类型方法。
  7. 不要一遍又一遍地从读取器中获取相同的值,将其存储在局部变量中。
  8. DateDiff 返回长而不是短
  9. 我怀疑您想要大于或等于,而不是等于,因为您似乎想要显示预订的距离。
  10. 您需要将 ToolStripStatusLabel1.Text 从字符串转换为 DateTime

例如...

    Dim d1 As DateTime = DateTime.Parse(ToolStripStatusLabel1.Text)

    Dim connString As String = "server=DESKTOP-69QA9LH\SQLEXPRESS; database=servicedb; integrated security=true"
    Using conn As New SqlConnection(connString)
        conn.Open()

        Dim query As String
        query = "select time,tableno from restaurant "
        Using command As New SqlCommand(query, conn)
            Using reader = command.ExecuteReader
                While reader.Read()

                    REM 0 because its the first column in the query. If you prefer to look it up, you can do reader.GetOrdinal("time")
                    Dim time As DateTime = reader.GetDateTime(0)
                    REM Its hard to tell from the posted code, so Im going to assume tableno is an int32
                    Dim tableNo As Int32 = reader.GetInt32(1)

                    Dim diff As Long = DateDiff(DateInterval.Minute, time, d1)

                    If tableNo = 2 AndAlso diff >= 5 Then
                        Button3.BackColor = Color.LawnGreen
                    End If
                    If tableNo = 2 AndAlso diff >= 10 Then
                        Button3.BackColor = Color.LawnGreen
                    End If
                    If tableNo = 2 AndAlso diff >= 15 Then
                        Button3.BackColor = Color.LawnGreen
                    End If
                    If tableNo = 1 AndAlso diff >= 5 Then
                        Button1.BackColor = Color.Brown
                    End If
                    If tableNo = 1 AndAlso diff >= 10 Then
                        Button1.BackColor = Color.Brown
                    End If
                    If tableNo = 1 AndAlso diff >= 15 Then
                        Button1.BackColor = Color.Brown
                    End If
                End While
            End Using
        End Using
    End Using

看到我当时所达到的,我又想到了一些事情:

  1. tableno 和按钮之间似乎有关系。
  2. 它总是将相同的颜色放在同一个按钮中。您可能希望颜色有所不同。

所以这里是循环部分的替换

                While reader.Read()
                    REM 0 because its the first column in the query. If you prefer to look it up, you can do reader.GetOrdinal("time")
                    Dim time As DateTime = reader.GetDateTime(0)
                    REM Its hard to tell from the posted code, so Im going to assume tableno is an int32
                    Dim tableNo As Int32 = reader.GetInt32(1)

                    Dim diff As Long = DateDiff(DateInterval.Minute, time, d1)

                    REM Consider turning this group of lines into a method which converts the diff to a color
                    Dim diffColor As Color = Color.Gray REM Default color
                    If diff >= 5 Then
                        diffColor = Color.LawnGreen
                    End If
                    If diff >= 10 Then
                        diffColor = Color.Brown
                    End If
                    If diff >= 15 Then
                        diffColor = Color.Red
                    End If

                    If tableNo = 1 Then
                        Button1.BackColor = diffColor
                    End If
                    If tableNo = 2 Then
                        Button3.BackColor = diffColor
                    End If
                End While

【讨论】:

  • 谢谢你的代码,但还有一件事..我可以把 d1 放在哪里?因为我收到关于 d1 丢失的错误。当我执行代码时,它显示“指定的演员表无效”错误
  • 它只是在循环之外,因为它不需要每次都重新计算(参见第一块代码,它在连接字符串的上方)。我没有发现缺少 Parse,所以我只是对其进行了编辑。
  • 我尝试实现以下场景。当用户单击按钮 5 时,它与数据库的时间差并取决于时间差使按钮 2 的颜色不同
  • 恕我直言,我已经回答了为什么它只处理第一行的发布问题;以及发布的代码的一大堆其他问题。我希望您可以通过查看上述答案来解决这个问题;但请随意将其发布为一个不同的问题。并阅读“How To Ask”链接,因为您需要明确您的要求。
【解决方案2】:

Richarddissimoanswer 的帮助下,我得到了以下代码。我刚刚将getDatetime 中的两件事更改为GetValue,效果很好。

Dim d1 As DateTime = DateTime.Parse(ToolStripStatusLabel1.Text)

Dim connString As String = "server=DESKTOP-69QA9LH\SQLEXPRESS; database=servicedb; integrated security=true"
Using conn As New SqlConnection(connString)
    conn.Open()

    Dim query As String
    query = "select time,tableno from restaurant "
    Using command As New SqlCommand(query, conn)
        Using reader = command.ExecuteReader
            While reader.Read()

                REM 0 because its the first column in the query. If you prefer to look it up, you can do reader.GetOrdinal("time")
                Dim time As DateTime = reader.getvalue(0)
                REM Its hard to tell from the posted code, so Im going to assume tableno is an int32
                Dim tableNo As Int32 = reader.getvalue(1)

                Dim diff As Long = DateDiff(DateInterval.Minute, time, d1)

                If tableNo = 2 AndAlso diff >= 5 Then
                    Button3.BackColor = Color.LawnGreen
                End If
                If tableNo = 2 AndAlso diff >= 10 Then
                    Button3.BackColor = Color.LawnGreen
                End If
                If tableNo = 2 AndAlso diff >= 15 Then
                    Button3.BackColor = Color.LawnGreen
                End If
                If tableNo = 1 AndAlso diff >= 5 Then
                    Button1.BackColor = Color.Brown
                End If
                If tableNo = 1 AndAlso diff >= 10 Then
                    Button1.BackColor = Color.Brown
                End If
                If tableNo = 1 AndAlso diff >= 15 Then
                    Button1.BackColor = Color.Brown
                End If
            End While
        End Using
    End Using
End Using

【讨论】:

  • 很遗憾你没有提到我明确指出的假设tableno 列的类型是Int32 是不正确的。我本可以编辑我的答案,然后你就可以接受了。那么它是什么类型的呢?如果它是某种字符串,您可以使用GetString,更改变量的类型,然后返回到您最初将tableno 与字符串进行比较。如果您必须使用GetValue 来表示时间,那么数据库中的该列是什么类型?
猜你喜欢
  • 2019-12-05
  • 1970-01-01
  • 1970-01-01
  • 2015-06-05
  • 1970-01-01
  • 2021-06-30
  • 1970-01-01
  • 2020-05-23
  • 1970-01-01
相关资源
最近更新 更多