0

I've created a windows application to display the data from SQL database to a gridview in a windows application. I used VB.net and SQL server to do that. While using where condition in the sql query I got the values which satisfies given data. Now I need to update the shown data. For that I used the sql query Update columnName = value where (the condition). the column name and value are got from the user using a textbox. When i used the query in Sql, it works fine and the value gets updated in database. But, When I run the same in VB code it doesn't gets updated in the windows application. I doesn't get it, and the assigned time for it runs beyond my watch time. Please, help me someone. Thanks in advance.Here I attach the code.

\ the code starts here \

Private Sub Btn_Edit_Click(sender As Object, e As EventArgs) Handles btn_Update.Click
        cmdupdate.Connection = connection
        connection.Open()
        'table.Rows.Clear()
        'table.Columns.Clear()

 cmdupdate.CommandText = "update tblWebaccessErrorTrack set @columnName = @editData where IssueDateTime between @frmdate and @todate and ErrorDetails like '%' + @errorDetails + '%' and  ClientIpaddress like '%'+ @IpAddress + '%' and ResponseStatus like '%'+ @responseStatus + '%' and TicketNo like '%' + @ticketNo + '%' select * from tblWebaccessErrorTrack"
        table.Clear()
        '"UPDATE tblWebaccessErrorTrack
        ' SET
        ' @columnName = @editData"
        '"sp_Updatedata"
        'Update tblWebaccessErrorTrack set TicketNo=202010 select * from tblWebaccessErrorTrack

        'cmdupdate.CommandType = CommandType.StoredProcedure
        cmdupdate.Parameters.Add("@frmdate", SqlDbType.DateTime).Value = frm_DateTimePicker.Text
        cmdupdate.Parameters.Add("@todate", SqlDbType.DateTime).Value = to_DateTimePicker.Text
        cmdupdate.Parameters.Add("@errorDetails", SqlDbType.NVarChar).Value = txtErrorDetails.Text
        cmdupdate.Parameters.Add("@IpAddress", SqlDbType.NVarChar).Value = txtClientIp.Text
        cmdupdate.Parameters.Add("@responseStatus", SqlDbType.NVarChar).Value = txtResponseStatus.Text
        cmdupdate.Parameters.Add("@ticketNo", SqlDbType.NVarChar).Value = txtTicketNo.Text
        cmdupdate.Parameters.Add("@columnName", SqlDbType.NVarChar).Value = Columnvalue '//column name
        cmdupdate.Parameters.Add("@editData", SqlDbType.NVarChar).Value = txtEditdata.Text '//Data we give

        adapter = New SqlDataAdapter(cmdupdate)

        adapter.Fill(table)
        adapter.Update(table)
        DataGridView1.DataSource = table
        'adapter.Fill(table)
        'table.Clear()


        'cmdupdate.CommandText = "select * from tblWebaccessErrorTrack" 'where IssueDateTime between @frmdate and @todate and ErrorDetails like '%' + @errorDetails + '%' and  ClientIpaddress like '%'+ @IpAddress + '%' and ResponseStatus like '%'+ @responseStatus + '%' and TicketNo like '%' + @ticketNo + '%'"
        'adapter = New SqlDataAdapter(cmdupdate)
        'adapter.Fill(table)
        'adapter.Update(table)
        'DataGridView1.DataSource = table
        ''adapter.Fill(table)
        ''cmdupdate.Parameters.Clear()
        'table.Clear()
        connection.Close()
        cmd.Parameters.Clear()

    End Sub`enter code here`
  • the character(') present in front of some line represents commented line.
Andrew Morton
  • 24,203
  • 9
  • 60
  • 84
  • 2
    You can't use a parameter for a column name. [Can I pass column name as input parameter in SQL stored Procedure](https://stackoverflow.com/questions/10092869/can-i-pass-column-name-as-input-parameter-in-sql-stored-procedure) has useful suggestions. – Andrew Morton Jan 06 '20 at 13:59
  • This is not a stored procedure so Andrew is incorrect. Update will only work if the data is in the database. You need to use Insert for new rows. – jdweng Jan 06 '20 at 14:28
  • @jdweng SP or not, you can't use a parameter for a column name (`set @columnName = @editData` in the question). The SP aspect is incidental. – Andrew Morton Jan 06 '20 at 14:32
  • Why not? This is SQL Server which accepts column names. – jdweng Jan 06 '20 at 14:47
  • @jdweng The column name cannot be a parameter. It's in the documentation: [UPDATE (Transact-SQL)](https://learn.microsoft.com/en-us/sql/t-sql/queries/update-transact-sql?view=sql-server-ver15). `SET column_name = expression` doesn't allow for column_name to be an expression; an expression includes a parameter. – Andrew Morton Jan 06 '20 at 15:10
  • @user12661874 Also, there seems to be `select * from tblWebaccessErrorTrack` tacked onto the end of the `update` command. – Andrew Morton Jan 06 '20 at 15:12
  • Stored Procedure is commented out. If column name is actually a field in the table, then the code is valid. And column name is not in the command text. – jdweng Jan 06 '20 at 15:26
  • @jdweng I am referring to the (outdented) line which starts `cmdupdate.CommandText = `, not the similar commented-out line later on. See Steven Doggart's answer at [Unable to select values when using a parameter for the column name](https://stackoverflow.com/a/16419380/1115360) if you'd like a second opinion. – Andrew Morton Jan 06 '20 at 15:30
  • With all those Like parameters are you expecting to update several rows? If not retrieve the Primary Key and identify the record to update with that. – Mary Jan 06 '20 at 16:41

1 Answers1

1

It will be easier if the code is split up into smaller pieces which each do one thing. It makes understanding and updating the code simpler. So, the methods to update a column and show the DGV would be separate.

For the SQL, please note that it is a bad idea to have just one SQL connection that gets re-used. There is a mechanism called connection pooling built in which makes the correct way of running a query a simple: create connection, use connection, dispose of the connection.

If you want to use a variable for the column name, then you have to concatenate it into the SQL query. This is open to SQL injection, so it is necessary to verify that a valid column name is being used before doing anything with it.

For the DateTimePickers, the value to use is the .Value, not the .Text, otherwise it could have problems with different Windows settings/locale.

So, this code is a starting point for getting it to work:

Private Function IsValidColumnName(colName As String) As Boolean
    'TODO: Put the valid column names in the array.
    Dim validColumnNames = {"Col1", "Col2", "ColWhatever"}
    Return validColumnNames.Any(Function(c) colName = c)

End Function

Private Sub UpdateDataInColumn(columnName As String, newData As String)
    If Not IsValidColumnName(columnName) Then
        Throw New Exception("Invalid column name [" & columnName & "]")
    End If

    Dim sql = "UPDATE tblWebaccessErrorTrack SET [" & columnName & "] & = @editData WHERE IssueDateTime BETWEEN @frmdate AND @todate AND ErrorDetails LIKE @errorDetails AND ClientIpaddress LIKE @IpAddress AND ResponseStatus LIKE @responseStatus AND TicketNo LIKE @ticketNo"

    Using conn As New SqlConnection("Your connection string"),
            cmdupdate As New SqlCommand(sql, conn)

        cmdupdate.Parameters.Add("@frmdate", SqlDbType.DateTime).Value = frm_DateTimePicker.Value
        cmdupdate.Parameters.Add("@todate", SqlDbType.DateTime).Value = to_DateTimePicker.Value
        cmdupdate.Parameters.Add("@errorDetails", SqlDbType.NVarChar).Value = "%" + txtErrorDetails.Text & "%"
        cmdupdate.Parameters.Add("@IpAddress", SqlDbType.NVarChar).Value = "%" + txtClientIp.Text & "%"
        cmdupdate.Parameters.Add("@responseStatus", SqlDbType.NVarChar).Value = "%" + txtResponseStatus.Text & "%"
        cmdupdate.Parameters.Add("@ticketNo", SqlDbType.NVarChar).Value = "%" + txtTicketNo.Text & "%"
        cmdupdate.Parameters.Add("@editData", SqlDbType.NVarChar).Value = newData '//Data we give

        Dim nChanged = cmdupdate.ExecuteNonQuery()

        If nChanged > 1 Then
            ' More than one row was updated. This is probably a Big Problem.
        End If

    End Using

End Sub

Private Sub ShowDataGridView()
    'TODO: write the ShowDataGridView() sub.
End Sub

Private Sub btn_Update_Click(sender As Object, e As EventArgs) Handles btn_Update.Click
    Dim colName = "Some method to select a column would go here."
    Dim newData = txtEditdata.Text

    UpdateDataInColumn(colName, newData)
    ShowDataGridView()

End Sub
Andrew Morton
  • 24,203
  • 9
  • 60
  • 84