0

I'm making a VB.NET (4.6) Windows form application that collects info on our servers and allows us to do reports on it. It's coming together nicely but I've run into an issue I can't figure out. One part of the project is a service that queries the info on available Windows updates from WSUS and then stores them in an SQL database - that part works fine. I'm now trying to present this data in a DataGridView using an SqlDataReader to query the info from the database and fill up a DataTable with the response. The problem is that when I use the reader, it puts the same record in the DataTable twice. I'm not sure what I'm doing wrong, and I'm sure it's something super simple. Perhaps one of you folks can spot the problem?

Note: Earlier in the application, the updateid's are stored as unique strings in a list called dbupdateidlist, the results are stored in a DataTable called dbupTable, and the datagridview I'm trying to update is called UpdateDeetsView.

Public Sub getUpdateDetails()

    For Each str As String In dbupdateidlist
        Dim commGetUpdateDetails As String = "select upTableId, title, classification, description, " +
        "releasedate, severity, articlenumber, url from updatedetails where updateid = '" + str + "'"
        Using connObj As New SqlClient.SqlConnection(connectionString)
            Using cmdObj As New SqlClient.SqlCommand(commGetUpdateDetails, connObj)
                connObj.Open()
                Using readerObj As SqlClient.SqlDataReader = cmdObj.ExecuteReader
                    While readerObj.Read

                        dbuptabid = readerObj("uptableid")
                        dbuptitle = readerObj("title")
                        dbupclass = readerObj("classification")
                        dbupdesc = readerObj("description")
                        dbupreleasedate = readerObj("releasedate")
                        dbupseverity = readerObj("severity")
                        dbuparticlenumber = readerObj("articlenumber")
                        dbupurl = readerObj("url")

                        row = dbupTable.NewRow()
                        row("uptableid") = dbuptabid
                        row("title") = dbuptitle
                        row("classification") = dbupclass
                        row("description") = dbupdesc
                        row("releasedate") = dbupreleasedate
                        row("severity") = dbupseverity
                        row("articlenumber") = dbuparticlenumber
                        row("url") = dbupurl
                        dbupTable.Rows.Add(row)
                    End While

                End Using
                connObj.Close()
            End Using
        End Using
    Next
    UpdateDeetsView.DataSource = dbupTable
End Sub

Forgive the likely terrible code, I'm an SA not a dev...

13
  • 1
    There is no need to move the rows one by one to a datatable. dbupTable.Load(readerObj.ExecuteReader) will fill the table for you. If you have that table elsewhere, you could just use a DataView of it. But by all means, turn on Option Strict Commented Apr 29, 2016 at 18:40
  • 2
    Even if just an SA, always use parameters to avoid SQL Injection and formatting issues. Commented Apr 29, 2016 at 18:41
  • 1
    Does dbupdateidlist contain duplicated values? Commented Apr 29, 2016 at 18:45
  • This is not a sql-server question, please use tags properly. Commented Apr 29, 2016 at 18:47
  • @Plutonix thanks for the tip! But, I replaced the entire While loop with dbupTable.Load(cmdObj.ExecuteReader) and it still shows two results. What would Option Strict do for me? Commented Apr 29, 2016 at 18:50

2 Answers 2

2

Try this:

Public Sub getUpdateDetails()
    Dim sql As String = _    
        "SELECT DISTINCT upTableId, title, classification, description, releasedate, " & _
            " severity, articlenumber, url " & _
       " FROM updatedetails " & _ 
       " WHERE updateid = @updateID"

    Using cn  As New SqlClient.SqlConnection(connectionString), _
          cmd As New SqlClient.SqlCommand(sql, cn)

        cmd.Parameters.Add("@updateID", SqlDbType.Int).Value = Int32.Parse(dbupdateidlist.First())
        cn.Open()
        UpdateDeetsView.DataSource = cmd.ExecuteReader()
    End Using
End Sub

Note the use of DISTINCT and the complete lack of any explicit loops whatsoever.

Also note that I'm only looking at one entry in dbupdateidlist. The real source of your old bug may have been to have the the ID in that list twice.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks a ton! This worked and suddenly only getting one row.
@user1806800 Contradicts your statement "I've run it in SMSS and I get the one result"
@Paparazzi I think the original problem was the ID value was in the dbupdateidlist list twice. Thus it was running the sql statement twice without clearing the datatable in between.
@JoelCoehoorn I asked the OP to test in SSMS and OP commented to me 1 row was returned
@Paparazzi Exactly. Notice this line from the question: For Each str As String In dbupdateidlist. There were two values in dbupdateidlist. So each row is returned by the query once, but the query ran twice. So the real fix in my answer is either the use of .First() to only get one entry, or assigning directly to the Datasource, which would clear items from any previous run.
|
0

There is no way readerObj.Read is failing to move to the next record

get the output of this and run it is SSMS

"select upTableId, title, classification, description, " +  
"releasedate, severity, articlenumber, url from updatedetails where updateid = '" + str + "'"

8 Comments

You may have misunderstood my question, it's returning two rows when only one exists. I've run it in SMSS and I get the one result, but if it's run by the reader I get the same row twice in the DataGridView.
@user1806800 That image is NOT proof that loop returned two rows. Trace it in debug mode and no way it loops twice if query returns one row. Knock, knock - if you call that twice than that is the results you would get.
@user1806800 I'd doublecheck the assumption that only one row exists
Knock, knock. You state "looping through through SqlDataReader returns the same row twice". That is false. The loop is not return the same row twice. If it is being called twice then you are calling it twice. The answer is yes you are doing something wrong - that loop is doing exactly was it is supposed to do.
Then what is? Again you're just saying I'm doing something wrong not offering any advice or possible solutions. Obviously, I came here knowing I'm doing something wrong. If I'm asking the question incorrectly the suggest an alternative or don't answer, this is just wasting our time.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.