VB.NET开发PTO带薪休假追踪器 执行SQL UPDATE语句出现语法错误
问题排查及修复方案
1. 直接触发SQL语法错误的原因
你的UPDATE语句末尾多了一个多余的右括号),不符合SQL语法规范,这是报错的直接诱因。
错误写法示例:
UPDATE TimeBank SET Bank = 'xxx', Protected = 'xxx')
直接删除末尾的)即可解决语法报错问题。
2. 其他需要修复的严重问题(会导致功能异常/数据错误)
- 缺少WHERE筛选条件:当前的UPDATE语句会修改
TimeBank表的所有行,所有用户的PTO余额都会被覆盖,必须补充WHERE条件限定要更新的目标记录,比如按用户ID、记录ID筛选。 - 数值更新逻辑顺序错误:你在方法最开头就把
lblBank、lblProtected的初始值赋值给了dblBank、dblProtected变量,后续的时长扣减、Protected时间的扣减逻辑都在SQL执行之后才运行,导致写入数据库的是未扣减的旧值,数据完全不对。 - SQL注入+格式风险:直接拼接变量到SQL字符串中,不仅可能因为小数分隔符、特殊符号触发二次语法错误,还存在SQL注入漏洞,必须改用参数化查询。
- 资源泄漏风险:数据库连接没有用
Using块托管,执行过程中如果出现异常,连接会一直保持打开状态,导致连接泄漏。 - 类型转换无校验:直接把Label的Text属性赋值给Double类型变量,没有做非空、合法性校验,遇到异常值会直接触发程序崩溃。
3. 修正后的代码示例
Private Sub btnSubmit_Click(sender As Object, e As EventArgs) Handles btnSubmit.Click ' 先校验必填项 If String.IsNullOrWhiteSpace(cboStart.Text) OrElse String.IsNullOrWhiteSpace(cboEnd.Text) Then MessageBox.Show("You must select a start and end time.", "Service Delivery PTO Tracker", MessageBoxButtons.OK, MessageBoxIcon.Error) Return End If ' 校验时间选择合法性 Dim startTime As DateTime Dim endTime As DateTime If Not DateTime.TryParse(cboStart.SelectedItem?.ToString(), startTime) OrElse Not DateTime.TryParse(cboEnd.SelectedItem?.ToString(), endTime) OrElse endTime <= startTime Then MessageBox.Show("请选择合法的起止时间", "Service Delivery PTO Tracker", MessageBoxButtons.OK, MessageBoxIcon.Error) Return End If ' 校验余额数值合法性 Dim dblBank As Double Dim dblProtected As Double If Not Double.TryParse(lblBank.Text, dblBank) OrElse Not Double.TryParse(lblProtected.Text, dblProtected) Then MessageBox.Show("余额数值异常", "Service Delivery PTO Tracker", MessageBoxButtons.OK, MessageBoxIcon.Error) Return End If ' 计算时长 Dim duration As TimeSpan = endTime - startTime Dim hours As Double = duration.TotalHours lblHours.Text = hours.ToString() ' 先完成所有扣减计算 dblBank -= hours If radProtected.Checked Then dblProtected -= hours End If ' 执行数据库更新,使用Using块自动释放连接和命令对象 Using con As New SqlConnection("你的数据库连接字符串") ' 这里替换成你实际的连接字符串 con.Open() ' 注意:补充你自己的WHERE条件,比如 WHERE 员工ID = @EmpId 之类的 Dim sql As String = "UPDATE TimeBank SET Bank = @Bank, Protected = @Protected WHERE 你的主键条件 = @Id" Using command As New SqlCommand(sql, con) ' 用参数化查询传值,自动处理格式、避免注入 command.Parameters.AddWithValue("@Bank", dblBank) command.Parameters.AddWithValue("@Protected", dblProtected) ' 这里替换成你要更新的记录的主键值,比如当前登录用户的ID command.Parameters.AddWithValue("@Id", 你要更新的记录ID) command.ExecuteNonQuery() End Using End Using ' 更新界面显示 lblBank.Text = dblBank.ToString() lblProtected.Text = dblProtected.ToString() MessageBox.Show("PTO Updated Successfully!") LoadDataGrid() ' 重置单选框 radProtected.Checked = False End Sub
内容的提问来源于stack exchange,提问作者cdepaul06
相关产品推荐
相关产品推荐

