【数据库】记录一次sql server在windows和linux服务器下安装,对于数据类型varchar和nvarchar的明显区别,你是否也遇到过中文匹配无法查询到数的情况

📅 2026/7/5 5:18:44
【数据库】记录一次sql server在windows和linux服务器下安装,对于数据类型varchar和nvarchar的明显区别,你是否也遇到过中文匹配无法查询到数的情况
欢迎来到《小5讲堂》这是《Sql Server》系列文章每篇文章将以博主理解的角度展开讲解。温馨提示博主能力有限理解水平有限若有不对之处望指正 作者简介 荣誉头衔2024博客之星Top14 | CSDN博客专家 | 阿里云专家博主 经历曾多次进行线下演讲亦是CSDN内容合伙人以及新星优秀导师 信念“帮助别人成长自己” 技术领域深耕全栈精通 .NET Core (C#)、Python、Java熟悉主流数据库 欢迎交流无论是基础概念还是进阶实战都欢迎与我探讨目录前言问题现象排查思路第一步检查数据类型第二步全匹配测试第三步排除隐藏字符根本原因排序规则差异Windows vs Linux Docker 默认排序规则为什么会匹配失败解决方案方案一查询加 N 前缀推荐方案二修改数据库排序规则治本经验总结参考文章推荐前言经常使用linux服务器的朋友可能会知道nvarchar和varchar的本质区别对于博主最近才接触linux服务器来说还是会才一点坑。原来nvarchar匹配查询中文数据时需要加一个N在前面否则无法查询到数据真是这十年开发经验白学了现在才知道必须给自己两巴掌反省反省。SQL Server迁移Linux DockerNVARCHAR查询为何失灵注意如果是title参数化就无需加N还有个情况就是varchar保存了中文但是在导入linux系统的mssql后出现了问号问题现象SQL Server从Windows迁移到Linux Docker后一条简单的查询语句返回了异常结果SELECTe_status_text,LEN(e_status_text),user_guidFROMmini_es_energyWHEREuser_guid36f48dfd-a0c3-4277-8f38-eeb163953858ANDe_status_textLIKE%已到账%明明表中有e_status_text 已到账的记录但LIKE %已到账%就是匹配不到而待到账、已退款等值却能正常显示。更诡异的是用LEN()和DATALENGTH()检查长度和字节数都正常3和6没有任何隐藏字符。排查思路第一步检查数据类型SELECTDATA_TYPE,CHARACTER_MAXIMUM_LENGTHFROMINFORMATION_SCHEMA.COLUMNSWHERETABLE_NAMEmini_es_energyANDCOLUMN_NAMEe_status_text;结果e_status_text为nvarchar(50)。第二步全匹配测试改用精确匹配依然查不到ANDe_status_text已到账-- 仍返回空第三步排除隐藏字符查看实际存储值及其长度SELECTe_status_text,LEN(e_status_text)AS长度,DATALENGTH(e_status_text)AS字节数FROMmini_es_energyWHEREuser_guid36f48dfd-a0c3-4277-8f38-eeb163953858;结果完全正常e_status_text长度字节数已到账36数据本身没问题问题出在比较规则上。根本原因排序规则差异Windows vs Linux Docker 默认排序规则环境默认排序规则中文支持Windows ServerChinese_PRC_CI_AS✅ 原生支持Linux DockerSQL_Latin1_General_CP1_CI_AS❌ 不支持中文代码页为什么会匹配失败字段e_status_text是nvarcharUnicode查询字符串已到账被当作varchar非Unicode处理在 Linux Docker 的Latin1排序规则下varchar无法正确转换为nvarchar进行中文比较导致字符匹配失败查询返回空简单说nvarchar字段 varchar条件 Latin1 排序规则 中文匹配失效。解决方案方案一查询加 N 前缀推荐所有涉及中文/Unicode字符串的条件统一加N前缀显式声明为 UnicodeSELECTe_status_text,LEN(e_status_text),user_guidFROMmini_es_energyWHEREuser_guid36f48dfd-a0c3-4277-8f38-eeb163953858ANDe_status_textN已到账;-- 匹配-- 或ANDe_status_textLIKEN%已到账%;-- 模糊匹配优点立即生效无需停机符合SQL Server最佳实践跨环境兼容。方案二修改数据库排序规则治本将数据库排序规则改为中文支持的规则需停机维护-- 查看当前排序规则SELECTname,collation_nameFROMsys.databasesWHEREname你的数据库名;-- 修改为中文排序规则需单用户模式ALTERDATABASE你的数据库名COLLATEChinese_PRC_CI_AS;⚠️注意此操作会影响所有字符串比较需重建部分索引生产环境请谨慎操作。经验总结nvarchar字段配N前缀是最佳实践无论在Windows还是Linux都应如此。跨平台迁移时排序规则差异是常见陷阱Windows上的“侥幸成功”不代表Linux上也能跑。迁移前检查排序规则SELECTSERVERPROPERTY(Collation)ASServerCollation;如果无法修改代码可在迁移时指定与Windows一致的排序规则来避免此问题。参考SQL Server Collation 官方文档Linux 上 SQL Server 的排序规则设置文章推荐【数据库】记录一次sql server在windows和linux服务器下安装对于数据类型varchar和nvarchar的明显区别你是否也遇到过中文匹配无法查询到数的情况【数据库】Sql ServerA表的a字段更新到B表的a字段基础知识点一分钟拿下【数据库】Sql Server数据库中isnull、iif、case when三种方式的使用和空值判断【数据库】如何使用一款轻量级数据库SqlSugar进行批量更新以及查看最终的Sql操作语句【数据库】使用Sql Server将分组后指定字段的行数据转为一个字段显示并且以逗号隔开每个值收藏不迷路【数据库】SQL Server 查询条件小技巧ISNULL 函数的使用有请DeepSeek来辅助讲解下【Sql Server】在SQL Server中生成雪花ID(Snowflake ID)【Sql Server】使用row_number over方式进行表分页数据量达到五千多条记录后查询变慢需要20多秒的解决方案【Sql Server】随机查询一条表记录并重重温回顾下自定义函数的封装和使用【Sql Server】锁表如何解锁模拟会话事务方式锁定一个表然后进行解锁【Sql Server】通过Sql语句批量处理数据使用变量且遍历数据进行逻辑处理【新星计划回顾】第六篇学习计划-通过自定义函数和存储过程模拟MD5数据【新星计划回顾】第四篇学习计划-自定义函数、存储过程、随机值知识点【Sql Server】Update中的From语句以及常见更新操作方式总结温故而知新不同阶段重温知识点会有不一样的认识和理解博主将巩固一遍知识点并以实践方式和大家分享若能有所帮助和收获这将是博主最大的创作动力和荣幸。也期待认识更多优秀新老博主。