You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET与数据库问题:首次扫描无IN记录,需生成空entry_record

问题分析与修复方案

问题根源

首次扫描时,monitoring表中不存在当前id_num的记录,第二个查询的dr.Read()返回False,导致While循环完全不执行。此时record变量保持初始空值,status.Text也未被赋值,最终插入数据库时entry_record字段就为空(NULL)。只有当表中已有记录时,循环才会触发,record才会被正确赋值,插入行为才正常。

另外还有两个潜在问题:

  • 查询monitoring表时如果存在多条同id_num的记录,While循环会反复覆盖record的值,最终只会保留最后一条记录的判断结果,逻辑不准确,应该取最新的一条记录来判断出入状态。
  • 初始未给record设置默认值,没有兜底逻辑。

修复后的代码

Private Sub TextBox7_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox7.KeyDown
    If e.KeyCode = Keys.Enter Then
        Dim idnum = TextBox7.Text
        ' 初始化默认值为IN,兜底首次扫描的情况
        Dim record As String = "IN"

        TextBox2.Text = ""
        TextBox3.Text = ""
        TextBox4.Text = ""

        ' 获取学生信息
        ConnectToDB()
        sql = "select * from rfidmaintest.student_details_dub where f9 = @idnum"
        cmd = New MySqlCommand(sql, cn)
        cmd.Parameters.AddWithValue("@idnum", idnum)
        dr = cmd.ExecuteReader

        While dr.Read
            TextBox2.Text = dr("f2").ToString()
            TextBox3.Text = dr("f9").ToString()
            TextBox4.Text = dr("f4").ToString()
            TextBox5.Text = dr("f14").ToString()
            TextBox6.Text = dr("f3").ToString()
            TextBox7.Clear()
        End While
        dr.Close()
        cn.Close()

        ' 查询最新的监控记录,判断出入状态
        ConnectToDB()
        ' 按日期倒序,只取最新一条记录
        sql = "select entry_record from rfidmaintest.monitoring where id_num = @idnum order by date desc limit 1"
        cmd = New MySqlCommand(sql, cn)
        cmd.Parameters.AddWithValue("@idnum", idnum)
        dr = cmd.ExecuteReader

        If dr.Read() Then
            Dim existingRecord As String = dr("entry_record").ToString()
            If existingRecord = "IN" Then
                record = "OUT"
            ElseIf existingRecord = "OUT" OrElse String.IsNullOrEmpty(existingRecord) Then
                record = "IN"
            End If
        End If
        status.Text = record

        dr.Close()
        cn.Close()

        ' 插入新记录
        ConnectToDB()
        sql = "insert into monitoring (id_num, fname, lname, status, entry_record, floor_level, date) VALUES (@num, @name, @lname, @stat, @record, @lev,@date)"
        cmd = New MySqlCommand(sql, cn)

        With cmd
            .Parameters.AddWithValue("@num", idnum)
            .Parameters.AddWithValue("@name", TextBox2.Text)
            .Parameters.AddWithValue("@lname", TextBox6.Text)
            .Parameters.AddWithValue("@stat", TextBox5.Text)
            .Parameters.AddWithValue("@lev", levellock.sharevalue)
            .Parameters.AddWithValue("@record", record) ' 直接用初始化后的record变量,避免依赖控件值
            .Parameters.AddWithValue("@date", Date.Now)
            .ExecuteNonQuery() ' 插入操作应该用ExecuteNonQuery,而不是ExecuteReader
        End With

        MsgBox("Details has been saved!", vbInformation, "Saved")

        cmd.Dispose()
        cn.Close()
    End If
End Sub

关键修改点

  1. 初始化默认值:将record初始化为"IN",确保首次扫描时即使没有历史记录,也能正确赋值。
  2. 优化查询逻辑:查询monitoring表时按date倒序并只取最新一条记录,避免多条记录导致的逻辑混乱。
  3. 替换执行方法:插入操作使用ExecuteNonQuery()而非ExecuteReader(),符合数据库操作规范(ExecuteReader()用于查询,ExecuteNonQuery()用于增删改)。
  4. 避免SQL注入:将第一个查询的字符串拼接改为参数化查询,提升安全性。
  5. 直接使用变量:插入时直接用record变量,避免依赖控件status.Text的值,减少潜在的控件值异常问题。

内容的提问来源于stack exchange,提问作者user19101467

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 02:25:29