问题

用python的pymssql模块读取旧业务系统后台SQL Server 2000数据库展示数据为乱码

开发环境

操作系统:windows 8

数据库 MS SQL Server 2000,默认配置

python 2.7.6

pymssql 2.1.1

开发工具:PyCharm 4.0

业务逻辑

数据库的[rooms]表记录一些功能房间列表,与其他接口数据进行对比,然后输出对比结果。

rooms表结构:

CREATE TABLE [rooms] (

[id] [int] IDENTITY (1, 1) NOT NULL ,

[name] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,

PRIMARY KEY CLUSTERED ([id] ON [PRIMARY] ,

UNIQUE NONCLUSTERED ([des]) ON [PRIMARY]

) ON [PRIMARY]

GO

模拟代码

# -*- coding: utf-8 -*-

import pymssql

rooms=None

with pymssql.connect(host='192.168.1.100',database='builds',

user='sa',password='password',

# charset='utf8',

) as conn:

cur=conn.cursor()

sql="select id,name from rooms"

cur.execute(sql)

rooms=cur.fetchall()

if rooms and isinstance(rooms,(list,tuple)):

for room_id,room_name in rooms:

print "\t".join([str(room_id),room_name])

在通用环境中运行代码,room_name变量列显示乱码

问题分析

调整连接字符集

首先想到的解决办法是,指定pymssql.connect参数charset的字符集值,使得内外数据编码一致。

依据,“默认情况下,SQL Server 2000使用ISO字符集(代码页1252)。这个字符集也叫ISO-8859-1 Latin1 或者ANSI字符集。它和Windows9x及Windows NT/2000操作系统相兼容,提供了与大多数语言最大兼容性。SQL Server2000中还包含代码页936(简体中文),该字符集包含对简体中文支持的字符”,将charset设置为gbk或cp936,更为合适。查看pymssql使用文档,发现官方没有给出此参数可接收的实例字符串。进行猜测性调试:

运行抛出异常:pymssql.OperationalError: (20017, 'DB-Lib error message 20017, severity 9:\nUnexpected EOF from the server\nDB-Lib error message 20002, severity 9:\nAdaptive Server connection failed\n')

调试模式下pymsql.connect无异常信息,但程序直接退出

运行正常,输出依然乱码;不指定此参数值时,程序使用默认值'UTF-8'

结论:此路不通

特定字符串调试

使用PyCharm调试程序,选定特定room_name值,来进行分析

# 注意此时输出标记为u,说明识别为unicode编码,正常时此时print出是真实值

>>> room_name

u'\xbf\xec\xb5\xdd\xbc\xe4\xa3\xa8\xc3\xc5\xc4\xda\xa3\xa9'

# 打印原始值为乱码,所以怀疑实际存储的是被标记为unicode的其他编码

>>> print room_name

¿ìµÝ¼ä£¨ÃÅÄÚ£©

# 这时可以将引号内赋值,再使用chardet.detect()判断

>>> aa='\xbf\xec\xb5\xdd\xbc\xe4\xa3\xa8\xc3\xc5\xc4\xda\xa3\xa9'

>>> aa

'\xbf\xec\xb5\xdd\xbc\xe4\xa3\xa8\xc3\xc5\xc4\xda\xa3\xa9'

# 果然,检测出的结果是GB2312编码

>>> chardet.detect(aa)

{'confidence': 0.99, 'encoding': 'GB2312'}

# 输出正常

>>> print aa.decode('gb2312')

快递间(门内)

# 此时,需要unicode->encode('Latin1')->decode('GB2312')

>>> room_name.encode('latin1').decode('GB2312')

u'\u5feb\u9012\u95f4\uff08\u95e8\u5185\uff09'

>>> print room_name.encode('latin1').decode('GB2312')

快递间(门内)

解决办法

pymssql基础实现使用的是cpython,从GitHub的官方代码文件_mssql.pyx,可以看到一些处理过程。使用strcpy函数对数据交换,因为对cpython不了解,怀疑是在处理双字节文字转码时的一点bug。

这个问题有两个解决办法:

代码中显式转码

方法:unicode变量.encode('latin1').decode('gbk'),详细情况可以参考下方的“PYTHON-进阶-编码处理小结”

一般情况下对unicode编码不做encode处理,但必要时可以encode为Latin1,实现脱unicode操作,然后再以合适字符集decode为正确unicode

print "\t".join([str(room_id),room_name.encode('latin1').decode('gbk')])

字符定义使用NVARCHAR

这种方式在存储和读取时都使用unicode编码,和python运转字节码一致,可以很好避免此类问题。当然数据库存储空间要牺牲一些。

[room_name] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL

原文:这里

参考:

mysql读出varchar乱码_pymssql读取varchar字段中文显示乱码的问题分析相关推荐

  1. mysql阿里云不显示中文乱码_MySQL命令窗口下中文显示乱码的解决过程

    MySQL命令窗口下中文显示乱码的解决过程 在dos客户端输出窗口中查询表中的数据,还有项目部署到服务器上时前台的页面,中文数据都显示成乱码,如下图所示: 这个问题困扰了我一天,后来解决了才发现原来我 ...

  2. centos7 文件名中文乱码_解决Centos7下中文显示乱码

    一.中文支持 安装中文语言包: 复制代码 代码如下: yum groupinstall chinese-support 修改字符编码配置,没有这个文件就创建它: 复制代码 代码如下: vim /etc ...

  3. debian命令乱码_Debian 9.5 解决中文显示乱码

    一.首先检查LOCALE情况 说明:DEBIAN因为基于GNU所以,对不同地域进行了不同的包支持,以LOCALE形式存在. 1.启动终端 #apt-get install locales 2.重新配置 ...

  4. centos组件显示乱码,centos组件显示乱码_解决CentOS下中文显示乱码

    查看当前系统语言 登陆Linux命令行,输入echo $LANG查看当前系统使用的语言 # echo $LANG 查看安装的语言包 在命令行中输入locale命令,如有zh_CN,则表示已经安装了中文 ...

  5. c mysql二进制,MySQL运用connector C/C+读取二进制字段

    MySQL使用connector C/C+读取二进制字段 MySQL使用connector C/C+读取二进制字段,两种方法: 用getString vector vec; while (pResul ...

  6. mysql的中文乱码url,MySQL 中文显示乱码

    MySQL 中文显示乱码 MySQL 中文显示乱码 如果你遇到乱码问题,可以从下面几个问题逐步检查: (1)检查你的文件存储编码是否和 meta 声明的一致,假如你的文件是按照 utf-8 编码存储, ...

  7. mysql 支持中文的字符集_MySQL 中文显示乱码

    最近关于中文显示乱码的贴子比较多,所以也做了个总结: 不同的编码格式会导致同一字符,在不同字符集下的编码会不同.同样同一编码在不同的字符集中代码的字符也不相同.当你的MySQL返回的字符串的编 码格式 ...

  8. sublime text html乱码,Sublime Text 2中文显示乱码的解决方法

    Sublime Text 2中文显示乱码的解决方法 发布时间:2014-05-12 15:30:14   作者:佚名   我要评论 这篇文章主要介绍了Sublime Text 2中文显示乱码的解决方法 ...

  9. MATLAB中文显示乱码的问题如何解决

    MATLAB中文显示乱码的问题如何解决 最近发现不同版本的 matlab 写的代码不能互用,比如在 matlab 2020 上写的代码,在matlab 2016 上显示,中文注释全部变成乱码,可能导致 ...

最新文章

  1. 远程连接linux服务器mysql
  2. 数字证书——密码学笔记(六)
  3. PPRevealSideViewController
  4. oracle导出建表主键,oracle主键自动生成 配合hibernate的生成策略详解
  5. 201671010119 2016-2017-2《Java程序设计》第十四周学习心得
  6. 前端笔记之JavaScript(十二)缓冲公式检测设备Data日期
  7. 读c语言深度剖析 -- 宏定义(2)
  8. 2021年中国研究生数学建模竞赛D题——抗乳腺癌候选药物的优化建模
  9. PHP 100 个最常用的函数
  10. (20191227已解决)从Linux服务器下载超过4G的文件并批量操作同类型文件
  11. Mysql 一次性执行多条语句的实现
  12. 仓库管理系统(warehouse management system)
  13. python 验证码 高阶验证
  14. 看完,如果你不分享,是我的失败!
  15. PMI-ACP练习题(17)
  16. 新年伊始,25岁“天才少年”曹原再发一篇Nature!9个月的第三篇Nature!
  17. winds添加静态路由
  18. 上海财经应用统计考python_2020考研:上海财经大学应用统计考研复习指南
  19. 计算机考研有哪些值得推荐的院校?能否具体讲讲?
  20. 第二届中国行业互联网大会暨CIO班十一周年年会首届阿拉善峰会圆满举行

热门文章

  1. honey select 模型导出_道路建模-基本模型
  2. 常见设计模式,单例模式(双重检测锁方式)示例
  3. mysql-连接查询
  4. 企业 SpringBoot 教程(六)springboot整合mybatis
  5. Sql Server中判断表或者数据库是否存在
  6. 视频监控日常使用存在哪些故障
  7. LocalResizeIMG前端HTML5本地压缩图片上传,兼容移动设备IOS,android
  8. 判断一件事有无技术含量的标准
  9. GSM协议编号及其内容
  10. 华章IT图书书讯(2012年第9期)