Reputation: 1
i have a set of strings in my textbox seperated with a comma each. i want to split them and update their record in db for each of the strings in the split. after running my code it only updates the first string and leave the rest. Here is my code.
Dim serialnumberlist = Split(txtserial.Text, ",").ToList
For Each serial As String In serialnumberlist
'update their branches
Dim constr As String = ConfigurationManager.ConnectionStrings("connectionstring").ConnectionString
Using con As New SqlConnection(constr)
con.Open()
Using cmd As New SqlCommand()
cmd.CommandText = "Update scratchcards set branches=@branches where Pin_Serial=@serial"
cmd.Parameters.AddWithValue("@branches", ddlbranches.SelectedValue)
cmd.Parameters.AddWithValue("@serial", serial)
cmd.Connection = con
cmd.ExecuteNonQuery()
End Using
End Using
Next
Response.Write("<script>alert('Branches allocated successfully!');</script>")
Upvotes: 0
Views: 129
Reputation: 96
Please try this way:
Dim serialnumberlist As String() = txtserial.Text.Split(","C)
For Each item As String In serialnumberlist
Using con As New SqlConnection("")
Using cmd As New SqlCommand("Update scratchcards set branches=@branches where Pin_Serial=@serial", con)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("@branches", ddlbranches.SelectedValue)
cmd.Parameters.AddWithValue("@serial", item )
cmd.ExecuteNonQuery()
End Using
End Using
Next
Upvotes: -1
Reputation: 131581
There doesn't seem to be anything wrong with your code, apart from a certain inefficiency. Perhaps the input is empty, or contains consecutive separators? You could avoid this confusion by using String.Split(Char(), StringSplitOptions) with StringSplitOptions.RemoveEmptyEntries
, which will remove empty entries.
If you suspect that theere may be multiple separators in the string, eg space-comma, you can add more separators in the separators
array.
As others have commented, you shouldn't rebuild the connection and command in each iteration. Your code should change to this:
Dim separators() As String = {","}
Dim serialnumberlist = txtserial.Text.Split(separators,StringSplitOptions.RemoveEmptyEntries)
'update their branches
Dim constr As String = ConfigurationManager.ConnectionStrings("connectionstring").ConnectionString
Using con As New SqlConnection(constr)
Using cmd As New SqlCommand()
cmd.Connection = con
cmd.CommandText = "Update scratchcards set branches=@branches where Pin_Serial=@serial"
cmd.Parameters.Add("@branches", SqlDbType.Int)
cmd.Parameters.Add("@serial", SqlDbType.NVarChar,30)
'At the moment of execution
cmd.Parameters("@branches").Value=ddlbranches.SelectedValue
con.Open()
For Each serial As String In serialnumberlist
cmd.Parameters("@serial").Value=serial
cmd.ExecuteNonQuery()
Next
End Using
End Using
Response.Write("<script>alert('Branches allocated successfully!');</script>")
Only the parameter value needs to change for each iteration.
You don't need to call .ToList()
after split as For Each
works with any IEnumerable
You can create the command in advance, even store it in a field for reuse. You only need to set a new Connection
befor each execution.
UPDATE
From the comments, it seems that the input data contains both a comma and a space, ie PA/3/0000001740, PA/1/0000004583, PA/4/0000000095
. To split this, the separator string ,
should be used, ie:
Dim separators() As String = {", "}
If there is any chance that a column may start withouth the space, the separators
array should contain both characters, ie:
Dim separators() As String = {",", " "}
or
Dim separators() As String = {", ",","}
Performance
Finally, the best performance for this update can be achieved if only one query is performed, ie UPDATE ... WHERE Pin_Serial in (....)
. This is risky though, as IN
expressions can't accept parameters. If the serials were numbers, one could validate the input and just join the keys. With text though, it's possible that unexpected values will create problems.
In this case, the query can be modified to use a table-valued parameter. That's a bit more involved though, and requires creating a table type in the database:
CREATE TYPE dbo.PinTableType AS TABLE ( Pin_Serial nvarchar(50) )
Once this is done though, the loop can become a single query:
UPDATE scratchcards
set branches=@branches
from scratchcards inner join @serialsTable on myTable.Pin_Serial=scratchcards.Pin_Serial
The @serialsTable
parameter will have to be of type DataTable
. I'll cheat a bit and use MoreLinq and ToDataTable() :
cmd.CommandText = "UPDATE scratchcards
set branches=@branches
from scratchcards inner join @serialsTable on myTable.Pin_Serial=scratchcards.Pin_Serial"
cmd.Parameters.Add("@branches", SqlDbType.Int)
cmd.Parameters.Add("@serialsTable",SqlDbType.Structured)
'At the moment of execution
cmd.Parameters("@branches").Value =ddlbranches.SelectedValue
Dim table as DataTable = serialnumberlist.ToDataTable()
cmd.Parameters("@serialsTable").Value=table
cmd.ExecuteNonQuery
Upvotes: 3
Reputation: 1331
Just as I thought, it's comma space... Either split on ", " or better, use the trim function
Dim serialnumberlist = Split(txtserial.Text, ",").ToList
For Each serial As String In serialnumberlist
'update their branches
Dim constr As String = ConfigurationManager.ConnectionStrings("connectionstring").ConnectionString
Using con As New SqlConnection(constr)
con.Open()
Using cmd As New SqlCommand()
cmd.Connection = con
cmd.CommandText = "Update scratchcards set branches=@branches where Pin_Serial=@serial"
cmd.Parameters.AddWithValue("@branches", ddlbranches.SelectedValue)
cmd.Paramaters.Add("@Serial", SqlDbType.Text)
For Each serial As String In serialnumberlist
cmd.Parameters("@Serial").Value = Trim(serial) '<--------HERE
cmd.ExecuteNonQuery()
Next
End Using
End Using
Response.Write("<script>alert('Branches allocated successfully!');</script>")
Upvotes: 0