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

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

时间:2024-08-13 14:38:20浏览次数:11  
标签:中文 String GBK 乱码 Oracle new US7ASCII properties

最近遇到一家客户的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);
    }

    @Test
    public 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();
            }
        });

    }

标签:中文,String,GBK,乱码,Oracle,new,US7ASCII,properties
From: https://www.cnblogs.com/lambdadog/p/18356892

相关文章

  • Oracle 19c通过recover standby database from service修复GAP案例
    案例介绍环境介绍操作系统:RedHatEnterpriseLinuxrelease8.10(Ootpa)数据库版本:Oracle19.23.0.0.0上周五,系统管理员需要给Linux升级补丁,UAT环境下的一套DG,数据库没有正常关闭的情况下,操作系统升级补丁后强制reboot了,周一早上处理的过程中遇到下面错误:备库的告警日......
  • 达梦数据库系列—47.DMHS实现Oracle12C到DM8的同步
    目录1、准备介质2、安装3、准备源端Oracle和目标端DM8软件安装数据库创建打开归档开启附加日志创建辅助表Oracle端安装ODBC创建连接用户创建测试用户和表4、同步配置修改服务配置Oracle到Dm单向同步配置Dm到Oracle单向同步配置5、启动DMHS服务初始装载装载数......
  • Oracle中exists和in的性能差异
    关于exists和inexists关键字和in关键字都能实现外表查询后的结果过滤功能。在SQL语句性能优化方面,建议exists代替in进行子查询,实际上二者分场景进行使用。低效SELECT*FROMEMP(基础表)WHEREEMPNO>0ANDDEPTNOIN(SELECTDEPTNOFROMDEPTWHERELOC='MELB')高效SE......
  • base64加密解密,中文乱码问题
    base64加密解密,中文乱码问题通常的方法是通过window.btoa()方法对源数据进行编码,然后接收方使用window.atob()方法对其进行解码,从而得到原数据.由于btoa方法仅支持ASCII编码,我们在转换中文的时候就需要先将中文转换为ASCII字符序列,再通过btoa进行base64编码,......
  • 【Oracle点滴积累】Oracle 19c安装Critical Patch Update for April 2022
    广告位招租!知识无价,人有情,无偿分享知识,希望本条信息对你有用!今天和大家分享如何为Oracle19c安装CriticalPatchUpdate(PatchNumber:33806138),本指引不包含RollBack部分。mkdir/home/oracle/Patchmkdir/home/oracle/PatchZipmkdir/home/oracle/Backup_ORACLE_H......
  • Oracle-OracleConnectorTask
    提示:OracleConnectorTask是一个Debezium连接器的具体实现,用于捕获Oracle数据库中的数据变化,并将这些变化以Kafka消息的形式发布出去。文章目录前言一、核心功能二、代码分析总结前言提示:OracleConnectorTask是一个重要的组件,它负责从Oracle数据库中捕获数据......
  • 14、Oracle中的Set运算符
    最近项目要用到Oracle,奈何之前没有使用过,所以在B站上面找了一个学习视频,用于记录学习过程以及自己的思考。视频链接:【尚硅谷】Oracle数据库全套教程,oracle从安装到实战应用如果有侵权,请联系删除,谢谢。学习目标:描述SET操作符将多个查询用SET操作符连接组成一个新的查......
  • 15、Oracle中的高级子查询
    最近项目要用到Oracle,奈何之前没有使用过,所以在B站上面找了一个学习视频,用于记录学习过程以及自己的思考。视频链接:【尚硅谷】Oracle数据库全套教程,oracle从安装到实战应用如果有侵权,请联系删除,谢谢。学习目标:书写多列子查询在FROM子句中使用子查询在SQL中使用单列子......
  • Oracle事务是怎么练成的
    什么是事务事务是数据库管理系统执行过程的一个逻辑单位,由一系列有限的数据库操作序列构成,事务必须满足‌ACID属性。ACID理论是数据库中最重要的概念之一,分别代表原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。原子性是指事务是一个不可分割的......
  • Oracle数据库巡检
    数据库巡检列表序号业务系统1主机名2操作系统4单机/RAC4IP地址5地址类型6数据类型7数据库版本8实例名巡检方案检查方面具体检查内容检查标准集群配置集群软件版本集群软件版本要等于或高于DB软件版本集群服务状态各种服务状态(除GSD外)需是ONLINE注:使用asfforrac的环境下......