当我点击更新按钮时我们的程序会更新数据网格视图中的所有数据,我们的代码有什么问题? 这是我们的代码
Private Sub btnUpdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUpdate.Click
con.ConnectionString = ("server=localhost;user id=root;password=;database=sample4")
Try
con.Open()
With cmd
.Connection = con
.CommandText = "UPDATE inventory SET product_name='" & txtPN2.Text & "',product_quantity='" & txtQuan2.Text & "',date='" & txtDate2.Text & "' WHERE 1"
result = cmd.ExecuteNonQuery
If result = 0 Then
MsgBox("Data has been already updated!")
Else
MsgBox("Successfully updated!")
.CommandText = "Select product_name,product_quantity,date from inventory"
txtPN2.Clear()
txtQuan2.Clear()
txtDate2.Clear()
txtPN2.Focus()
End If
End With
Catch ex As Exception
MsgBox(ex.Message)
End Try
con.Close()
End Sub
答案 0 :(得分:1)
这里有很多错误,包括工作中的逻辑错误和不良做法 首先从逻辑错误开始:
您认为这句话有什么作用? WHERE 1
(我甚至不知道你的数据库是否接受它,但假设它有效)。它没有找到要更新的精确记录,它让表中的每条记录都接收SET列表中指定的相同值。您需要传递密钥以标识要更新的精确记录。像WHERE KeyField=KeyValue
这样的地方,其中KeyField是表Invetory中列的名称,其值是唯一的,因此只为更新选择了一条记录
第二个逻辑问题:If result = 0 Then
这是错误的,因为ExecuteNonQuery的结果是更新/插入/删除的记录数。在您的情况下,UPDATE sql如果找到则更新始终是记录。如果值与以前相同,它也会更新记录。零反而意味着WHERE子句没有找到任何记录(在第一步中修复它之后)。因此,如果结果为零,则表中不存在与WHERE子句匹配的记录。
现在是不好的做法。
SET product_name='" & txtPN2.Text &.....
这是一个构建sql语句的字符串连接。错在很多层面上。如果您的一个文本框包含单引号,则整个文本在语法上会变得无效。最后,恶意用户可以在这些文本框中编写任何内容并创建可能破坏数据库或获取敏感信息的Sql Injection hack。您应该使用参数化查询
.CommandText = "UPDATE inventory SET product_name=@prod " & _
",product_quantity=@qty,date=@dt WHERE keyField=@kvalue"
.Parameters.Add("@prod", SqlDbType.NVarChar).Value = txtPN2.Text
.Parameters.Add("@qty", SqlDbType.Int).Value = Convert.ToInt32(txtQuan2.Text)
.Parameters.Add("@qty", SqlDbType.DateTime).Value = Convert.TODateTime(txtDate2.Text)
.Parameters.Add("@kvalue", SqlDbType.Int).Value = kvalue
result = cmd.ExecuteNonQuery
第二个不良做法:保持全局对象的连接和命令。这些是一次性物品,它们应该以众所周知的模式使用。创建,使用,销毁尽快释放宝贵的系统资源。保持全球收益不会给你带来任何损失,你就有可能泄漏资源。保持全局(或更好地从app.config读取)连接字符串并在连接和命令周围应用using语句