VB.Net中使用OleDbConnection搜索MDB/ACCDB内Unicode文本时抛出OleDbException的原因及解决办法
我来帮你搞定这个Unicode搜索的坑!先从你遇到的错误说起,再一步步给解决方案:
错误含义解释
你看到的Syntax error (missing operator)错误,核心原因是Access的OLE DB引擎不支持SQL Server风格的N'...'前缀。N前缀是SQL Server用来标识Unicode字符串的语法,但Jet/ACE引擎(Access的数据库引擎)根本不认这个写法,直接加N会让SQL语句语法混乱,所以抛出了语法错误。
为什么之前的尝试没结果?
你试过的LIKE '*வா*'无结果,大概率是两个原因:
- 字段类型不对:如果你的
NotesDetail字段是Access里的Short Text(原Text类型),它默认是ANSI编码,无法正确存储泰米尔文这类Unicode字符——即使你存进去了,搜索时也匹配不上。 - 通配符问题:Access默认在ANSI SQL模式下用
%作为LIKE通配符,*是旧的Jet模式通配符,可能和你的连接设置不匹配。
正确的解决方案
按照以下步骤操作,就能正常搜索Unicode文本:
1. 确保字段是Unicode兼容类型
打开你的ACCDB数据库,把NotesDetail字段的类型改成Long Text(原Memo类型)。Access的Long Text默认支持Unicode存储,能正确保存泰米尔文这类非ANSI字符。如果之前是MDB转来的,一定要检查字段类型,否则Unicode字符可能早就丢失了。
2. 使用参数化查询(推荐,安全又可靠)
直接拼接SQL字符串不仅有Unicode问题,还存在SQL注入风险。用参数化查询能完美解决编码问题,同时提升安全性:
' 连接ACCDB的正确字符串 OleDbConn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Db.accdb;" ' 用占位符?代替直接拼接字符串 Dim sql As String = "SELECT * FROM TableNotes WHERE NotesDetail LIKE ?" da = New OleDb.OleDbDataAdapter(sql, OleDbConn) ' 添加Unicode类型的参数,%是Access的通配符 da.SelectCommand.Parameters.Add("@SearchText", OleDbType.VarWChar).Value = "%" & "வா" & "%" da.Fill(ds, TableResult)
这里指定OleDbType.VarWChar告诉引擎这是一个Unicode字符串,能正确识别泰米尔文。
3. 如果一定要字符串拼接(不推荐)
如果你暂时不想改参数化查询,确保VB.Net的字符串是Unicode(VB.Net的String默认就是Unicode),并且字段是Long Text类型,直接拼接即可,不要加N前缀:
Dim searchUnicode As String = "வா" sql = "SELECT * FROM TableNotes WHERE NotesDetail LIKE '%" & searchUnicode & "%'" da = New OleDb.OleDbDataAdapter(sql, OleDbConn) da.Fill(ds, TableResult)
但再次提醒:这种方式有SQL注入风险,生产环境一定要用参数化查询。
4. 确认驱动支持
确保你安装了Microsoft.ACE.OLEDB.12.0驱动(Office 365或Access Runtime都包含这个驱动),Jet 4.0驱动(用于MDB)对Unicode的支持很差,转ACCDB用ACE驱动是正确的选择。
内容的提问来源于stack exchange,提问作者Mg Bhadurudeen

