What is the fastest way to update SQL rows with values, based upon a value in the row?

落爺英雄遲暮 提交于 2020-05-31 06:30:31

问题


I have the following table in SQL Server called tblProducts:

+-----------+--------------+-------------+
| pkProduct | fkProductID  |  intIssue   |
+-----------+--------------+-------------+
|     1     |     10       |      1      |
|     2     |     10       |      2      |
|     3     |     10       |      4      |
|     4     |     11       |      1      |
|     5     |     11       |      2      |
|     6     |     11       |      3      |
|     7     |     11       |      5      |
|     8     |     12       |      1      |
|     9     |     13       |      1      |
|     10    |     13       |      4      |
|     11    |     14       |      1      |
|     12    |     14       |      3      |
|     13    |     14       |      6      |
|     14    |     15       |      1      |
|     15    |     16       |      1      |
+-----------+--------------+-------------+

Over time, with rows having being deleted for whatever reasons, there are now gaps in the issue numbers. I would like the issue numbers to run in order so as the table looks like this:

+-----------+--------------+-------------+
| pkProduct | fkProductID  |  intIssue   |
+-----------+--------------+-------------+
|     1     |     10       |      1      |
|     2     |     10       |      2      |
|     3     |     10       |      3      |
|     4     |     11       |      1      |
|     5     |     11       |      2      |
|     6     |     11       |      3      |
|     7     |     11       |      4      |
|     8     |     12       |      1      |
|     9     |     13       |      1      |
|     10    |     13       |      2      |
|     11    |     14       |      1      |
|     12    |     14       |      2      |
|     13    |     14       |      3      |
|     14    |     15       |      1      |
|     15    |     16       |      1      |
+-----------+--------------+-------------+

At the moment I have added the table to my DataSet and using this in vb.net code i update the rows:

Dim currentProductsTable As tblProductsDataTable

Using taProduct As New tblProductsTableAdapter
    currentProductsTable = taProduct.GetData
End Using

Dim issueCounter As Integer = 1
Dim previousRow As tblProductsRow = Nothing

Using con As SqlConnection = New SqlConnection(My.Settings.MyConnectionString)
    Using cmd As New SqlCommand("UPDATE dbo.tblProducts SET [intIssue] = @issueCounter WHERE pkProduct = @ProductID", con)
        cmd.Connection = con 
        con.Open()
        For Each row As tblProductsRow In currentProductsTable.Rows
            If Not previousRow Is Nothing Then
                If row.fkProductID = previousRow.fkProductID Then
                    cmd.Parameters.Clear()
                    cmd.Parameters.Add("@issueCounter", SqlDbType.Int).Value = issueCounter
                    cmd.Parameters.Add("@ProductID", SqlDbType.Int).Value = row.pkProduct
                    previousRow = row
                Else
                    issueCounter = 1
                    cmd.Parameters.Clear()
                    cmd.Parameters.Add("@issueCounter", SqlDbType.Int).Value = issueCounter
                    cmd.Parameters.Add("@ProductID", SqlDbType.Int).Value = row.pkProduct
                    previousRow = row
                End If
            Else
                issueCounter = 1
                cmd.Parameters.Clear()
                cmd.Parameters.Add("@issueCounter", SqlDbType.Int).Value = issueCounter
                cmd.Parameters.Add("@ProductID", SqlDbType.Int).Value = row.pkProduct
                previousRow = row
            End If
            cmd.ExecuteNonQuery()
            issueCounter += 1
        Next
    End Using
End Using

I have ordered the .GetData by fkProductID ASC, and intIssue ASC, but it takes a very long time as there are around 30000 rows in the table.

I wondered if there was a faster way to do this kind of updating?


回答1:


I am going to guess that you are using SQL Server. If so, you can do this all in one query:

with toupdate as (
      select p.*,
             row_number() over (partition by fkProductID order by pkProduct) as new_intIssue
      from dbo.tblProducts p
     )
update toupdate
    set intIssue = new_intIssue
    where intIssue <> new_intIssue;


来源:https://stackoverflow.com/questions/52030582/what-is-the-fastest-way-to-update-sql-rows-with-values-based-upon-a-value-in-th

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!