Oracle数据库US7ASCII字符集中文乱码

news/2024/9/19 15:44:26/文章来源:https://www.cnblogs.com/lambdadog/p/18356892

最近遇到一家客户的Oracle数据库,版本是11g,字符集是US7ASCII,当使用PL/SQL Developer工具插入和查询中文时都没问题,但是Java程序使用JDBC插入和查询中文时,中文乱码。
比如'a中文b'通过JDBC查询出来的乱码是这样的'aᅱ￐ᅫᅣb'

查询了一些资料,看到有网友通过这种方式解决了(只列出关键代码)。但是这个方法对于我的环境没有效果。

        Properties properties = new Properties();properties.setProperty("serverEncoding","ISO-8859-1");properties.setProperty("clientEncoding","GBK");String DBURL = "jdbc:wrap-jdbc:filters=encoding:jdbc:oracle:thin:@//100.100.100.100:1521/helowin";

理论上来说,US7ASCII是不能保存中文的,因为ASCII编码一个字符只占用一个字节,即8位,而且首位是0. 但是看PL/SQL Developer的确把中文查出来了,挺让人疑惑的(后面想可能是因为PL/SQL用的胖客户端,做了某些处理,而JDBC用的是瘦客户端)。

通过查看16进制,我们可以看到,数据是这样保存的,再用计算器算一下,我们可以看到,每个中文其实占用了两字节,每个字母占用了1字节,而且中文字节是1开头,挺像GBK编码方式的。

而Oracle驱动中,如果采用ResultSet的getString方法来获取值,会走到这么一段代码中去,这段代码获取到的char[]其实把每个中文拆分成了两个字符去处理,所以得到的结果是乱码,而且乱码部分的字符数是中文数的两倍。

经过测试发现采用ResultSet的getBytes(int columnIndex)方法先得到byte数组,再用new String转GBK可以得到正常的中文。

最终我的解决方法:
插入数据时,对可能存在中文的值进行一次转码

String newName = new String(textValue.getBytes("GBK"), "ISO-8859-1");

查询数据时,对于VARCHAR2和CHAR类型的列,从ResultSet中获取值时先用getBytes(int columnIndex)方法,然后再用new String(byte bytes[], String charsetName) 转为GBK
以下是我对NAME字段进行处理的例子。

    private Connection getOracleConnection() throws Exception {Class.forName("oracle.jdbc.OracleDriver");Properties properties = new Properties();properties.setProperty("user", "YourUser");properties.setProperty("password", "YourPassword");String url = "jdbc:oracle:thin:@//100.100.100.100:1521/helowin";return DriverManager.getConnection(url,properties);}@Testpublic void connSelect() throws Exception {Connection connection = getOracleConnection();PreparedStatement preparedStatement = connection.prepareStatement("select * from JDBI_TEST");ResultSet resultSet = preparedStatement.executeQuery();if (resultSet == null) {return;}ResultSetMetaData metaData = resultSet.getMetaData();int columnCount = metaData.getColumnCount();List<Map<String, Object>> list = new ArrayList<>();while (resultSet.next()) {Map<String, Object> map = new HashMap<>();for (int i = 0; i < columnCount; i++) {String columnName = metaData.getColumnName(i + 1);if (!"NAME".equals(columnName)) {continue;}byte[] bytes = resultSet.getBytes(i + 1);map.put(columnName, bytes);}list.add(map);}list.forEach(map -> {Object name = map.get("NAME");try {logger.info("name: {}, {}", Arrays.toString((byte[]) name), new String((byte[]) name, "GBK"));} catch (UnsupportedEncodingException e) {e.printStackTrace();}});}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/783264.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VF01/VF02/VF03屏幕增强及BAPI增强字段处理

1.在销售发票抬头表中增加增强字段2.创建处理程序 主程序SAPMV60A中的所有包含文件都是以MV60AF打头的,所以我们创建一个独立的程序 SE38(ZSDU0001) 来存放所有的处理代码 创建屏幕9001,确保屏幕类型为子屏幕 屏幕字段可从VBRK表中获取*&--------------------------------…

GameSalad-IOS-游戏开发学习手册-全-

GameSalad IOS 游戏开发学习手册(全)原文:Learn GameSalad for iOS Game Development for iPhone, iPad, and HTML5 协议:CC BY-NC-SA 4.0零、简介 2007 年,苹果推出了 iPhone,彻底改变了我们的生活方式,但最重要的是 iOS 的诞生。今天,iOS 被用于 iPhone、iPad 和 iPo…

问题 IDEA创建Sping项目只能勾选17和21,却无法使用Java8

想创建一个springboot项目,本地安装jdk版本为1.8,但是在使用 Spring Initializr创建项目时,版本只能选择21或17 在JDK为1.8的情况下,无论选择Java17版本或者21版本时,都会报错。 Java17和Java 8(JDK1.8)的区别 版本号:Java 17 是 Java SE 17 的版本,而 JDK 1.8 是 Java S…

软件逆向之OD

OD全称OllyDbg ,是一种具有可视化界面的 32 位汇编-分析调试器。和IDA不同之处在于可以动态调试软件功能,可以有效的去分析程序构成。 以下软件讲解均以吾爱破解中的OD进行讲解。软件下载 打开程序主页面我们可以看到以下内容首先介绍一下软件主页面的4个窗口: 反汇编窗口:…

vue随笔

插值语法中可以使用三元表达式

Halcon颜色识别

本文接扫halcon识别排序颜色,复杂点在于无法使用单一图像区域识别出5中颜色。这里用到了ImageR 和 ImageS*颜色识别*定义颜色类型 FushColor := [black,brown,red,pink,yellow]*颜色对应灰度值 HueRange := [10,51,68,100,145,191,\0,10,30,50]*定义获取到的坐标,展示颜色 Ad…

Deno-入门指南-全-

Deno 入门指南(全)原文:Introducing Deno 协议:CC BY-NC-SA 4.0一、为什么是 Deno? 在过去的 10 年里,当后端开发人员听到“后端的 JavaScript”这个词时,所有人都会立即想到 Node.js。 在这 10 年的开始,也许不会马上出现,但最终它的名字为每个人所知,成为另一种基于…

CSS-框架替代指南-全-

CSS 框架替代指南(全)原文:CSS Framework Alternatives 协议:CC BY-NC-SA 4.0一、为直观的网页设计选择轻量级框架 什么是框架? A framework is a premeditated set of concepts, modules, and standardized criteria that make the task of developing web sites and web…

dicom 字符集的选择

查看字符集读取标签 特定字符集(0008,0005)字符集unicode是字符集,ASCII、GB2312、GBK、GB18030既是字符集也是编码方式,UTF-8只是编码方式 通过字符集中文字符集字符集的选择 不同厂商实现不同 修改导致不可读[ISO / IEC 10646]现在禁止使用除UTF-8的最小长度编码以外的…

日出日落

日出日路,跟日期,经纬度有关,满足以一年为周期,正弦余弦函数.见下图: 在PHP 中date_sunrise和date_sunset函数分别获取日出日落.date_sunrise(strtotime(日期),SUNFUNCS_RET_STRING,$latitude,$longitude,$zenith,$gmtoffset); date_sunset(strtotime(日期),SUNFUNCS_RET_STRIN…

关于小程序使用OCR进行身份证识别

1.第三方插件安装 2.搜索并安装 3.购买免费次数1天100次 https://fuwu.weixin.qq.com/service/detail/000ce4cec24ca026d37900ed551415 4.选中使用的账号 5.支付完成愉快使用 6.正式使用 文档位置:https://mp.weixin.qq.com/wxopen/plugindevdoc?appid=wx4418e3e031e551b…