VB.NET中MySQL多表联合查询及TextChanged搜索失效问题求助
问题排查与修复方案
我来帮你梳理下搜索功能失效的原因,主要是SQL语句的逻辑错误,还有几个需要优化的点,让我们一步步解决:
1. 核心问题:SQL语句的过滤范围错误
你当前的TextChanged事件里的SQL语句,WHERE子句只作用在第二个表moe上,而第一个表igo的所有行都会被返回,不管搜索内容是什么。这就导致搜索结果总是包含igo表的全部数据,自然达不到预期的搜索效果。
错误的SQL逻辑:
SELECT DISTINCT * FROM igo UNION SELECT DISTINCT * FROM moe WHERE full_name LIKE '%" & TextBox1.Text & "%' OR mothername LIKE '%" & TextBox1.Text & "%'"
等价于:
(SELECT DISTINCT * FROM igo) -- 这里没有任何过滤,返回所有行 UNION (SELECT DISTINCT * FROM moe WHERE full_name LIKE '%xxx%' OR mothername LIKE '%xxx%') -- 只有moe表被过滤
修正后的SQL:
需要给每个表的查询都加上过滤条件,确保两个表的行都被搜索文本过滤:
SELECT DISTINCT * FROM igo WHERE full_name LIKE @searchText OR mothername LIKE @searchText UNION SELECT DISTINCT * FROM moe WHERE full_name LIKE @searchText OR mothername LIKE @searchText
2. 必须修复:SQL注入风险
直接把TextBox的文本拼接进SQL语句是非常危险的操作,恶意用户可以通过输入特殊字符篡改SQL逻辑,导致数据泄露或破坏。我们需要用参数化查询来解决这个问题。
3. 优化数据库连接管理
当前代码中类级别的SqlConnection可能会导致连接泄漏,最好使用Using语句自动管理连接的生命周期,确保连接被正确释放。
完整修复后的代码
Imports System.Data.SqlClient Public Class Form1 Private Sub searchData(sql As String, dtg As DataGridView, Optional parameters As List(Of SqlParameter) = Nothing) Try ' 使用Using语句自动管理连接、命令、适配器的资源 Using con As New SqlConnection("Data Source=DESKTOP-C4O1PB3;Database=main_it;trusted_connection=true;") Using cmd As New SqlCommand(sql, con) ' 添加参数(如果有) If parameters IsNot Nothing Then cmd.Parameters.AddRange(parameters.ToArray()) End If Using da As New SqlDataAdapter(cmd) Dim dt As New DataTable() da.Fill(dt) dtg.DataSource = dt End Using End Using End Using Catch ex As Exception MsgBox(ex.Message) End Try End Sub Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load ' 加载所有数据(和搜索为空时的逻辑一致) LoadAllData() End Sub Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged Dim searchText As String = TextBox1.Text.Trim() If String.IsNullOrEmpty(searchText) Then ' 如果搜索框为空,加载所有数据 LoadAllData() Return End If ' 带参数的SQL语句 Dim sql As String = "SELECT DISTINCT * FROM igo WHERE full_name LIKE @searchText OR mothername LIKE @searchText " & "UNION " & "SELECT DISTINCT * FROM moe WHERE full_name LIKE @searchText OR mothername LIKE @searchText" ' 创建参数,注意添加通配符% Dim parameters As New List(Of SqlParameter)() parameters.Add(New SqlParameter("@searchText", "%" & searchText & "%")) searchData(sql, DataGridView1, parameters) End Sub ' 封装加载所有数据的逻辑 Private Sub LoadAllData() Dim sql As String = "SELECT DISTINCT * FROM igo UNION SELECT DISTINCT * FROM moe" searchData(sql, DataGridView1) End Sub End Class
额外说明
- 如果你的4个表都需要搜索,只需要在SQL语句中继续添加
UNION SELECT DISTINCT * FROM 表名 WHERE ...的部分即可,注意每个表的列数和数据类型必须一致(UNION的要求)。 - 使用
Trim()处理搜索文本可以避免用户输入空格导致的无效搜索。 Using语句会自动调用对象的Dispose()方法,不用手动写Dispose()和Close(),更安全可靠。
内容的提问来源于stack exchange,提问作者necolas
相关产品推荐
相关产品推荐

