Oracle里令人头疼的生僻字处理案例

2024-05-09 12:12

本文主要是介绍Oracle里令人头疼的生僻字处理案例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

事情起因

有小伙伴找到我问一下生僻字的问题,数据库是oracle 11g,字符集是zhs16gbk
 

image.png


下图里显示的??应该是“𧿹”这个字,算是个生僻字。
 

image.png


问应用厂家就说数据库字符集建错了,要改库的字符集。what???,这库都用了好几年了,现在改库字符集也不现实啊。
检查下字典点,看表里也是??显示

image.png

模拟测试

为了测试, 先创建个测试表,第1列是varchar2,第2列是nvarchar2
这里为了方便测试,使用scott用户

CREATE TABLE "SCOTT"."TEST_NAME" ( "BIANMA" NUMBER NOT NULL ENABLE, "VARCHAR2_NAME" VARCHAR2(200 BYTE), "NVARCHAR2_NAME" NVARCHAR2(200), CONSTRAINT "TEST_NAME_PK" PRIMARY KEY ("BIANMA") USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE( INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) TABLESPACE "USERS" ENABLE ) SEGMENT CREATION DEFERRED PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING STORAGE( INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) TABLESPACE "USERS" ;

创建如下图
 

image.png


这里提供几个把生僻字转换为Unicode的网址

http://unicode.wiicha.com/
https://www.bejson.com/convert/unicode_chinese/

查询一下这个字
 

image.png


\u是转换字符,用的时候去掉
查询一下

select utl_raw.cast_to_nvarchar2('d85fdff9') from dual;

image.png

在库里组合查询一下,看出来也可以显示

select utl_raw.cast_to_nvarchar2('d85fdff96307') from dual;

image.png


更新一下两个列里的内容

insert into  test_name  values (1,(select utl_raw.cast_to_nvarchar2('d85fdff96307') from dual),(select utl_raw.cast_to_nvarchar2('d85fdff96307') from dual));
commit;
select * from test_name

image.png

可以看出来,使用这种unicode转换的方式,只对nvchar2生效,varchar2还是显示乱码

关于varchar2和nvchar2

引用ASKTOM里的解答
NVARCHAR Vs. VARCHAR - Ask TOM (oracle.com)

Thanks for the question, Andrew.
Asked: September 04, 2015 - 3:00 pm UTC
Last updated: February 25, 2020 - 8:20 am UTC
Version: 12.0.2
Viewed 50K+ times! This question is 

img

You Asked
In a database with character sets defined as:
NLS_CHARACTERSET = AL32UTF8
NLS_NCHAR_CHARACTERSET = UTF8
Would there be any difference in the (language) character sets that could be stored by VARCHAR2 Vs. NVARCHAR2? As in
NAME VARCHAR2(60 CHAR)
Vs.
NAME NVARCHAR2(60 CHAR)
and Chris said…
NVARCHAR2 is a unicode-only data type. It’s useful if you want to have unicode for some columns (those that are NVARCHAR2) but have the rest of the database use a different characterset. In all other cases stick with using VARCHAR2.
In your case the only difference between UTF8 and AL32UTF8 is the AL version includes “supplementary characters”.
See also:
http://www.oracle.com/technetwork/database/database-technologies/globalization/twp-appdev-unicode-10gr2-129234.pdf
and
http://docs.oracle.com/database/121/NLSPG/ch6unicode.htm#NLSPG006

解决办法

根据以上测试的情况来看,有几个方案:
方案1、列由原来的varchar2改为nvarchar2,再插入unicode编码。
方案2、新建个utf8字符集的库,导出现有全库,再导入回去。
方案3、𧿹改写成别的可识别字符,如(足母)代替。
下面一个一个说一下几个方案:
方案1
需要停业务改表,结构,测试了一下,varchar2可以直接改成nvarchar2,但是nvarchar2改成varchar2要求必须没有数据。实际生产我也没测试过直接改列的字段类型,不知道会不会有问题。。
目前从网上收录2个操作方法
操作A
1、将表字段修改类型为:NVARCHAR2(),无论该字段是否存值都可以直接修改 alter table 表名 modify (字段名 nvarchar2(20));
注:如果想从NVARCHAR2()改回VARCHAR2,会报错:“ORA-01439:要更改数据类型,则要修改的列必须为空”,
解决方案为:①、将该字段A改名B;②、新建表字段,命名为A,将B值更新到A;③、删除B字段
2、使用该sql将生僻字插入到表中: update 表名 set 字段名 = N’生僻字’ where …
注意set字段名字前一定要有N,且在’'外。
操作B
也有人提供一个中转的解决办法:
修改字段类型,需要先将该字段清空,如果需要保存数据,可以先建一个临时的字段存储这些数据,然后删除要修改的列,再重新创建

--临时字段
alter table test_name add TEMP nvarchar2(200);
--赋转换后的值
update test_name set TEMP=cast(VARCHAR2_NAME as nvarchar2(200));
commit;
--删除字段
alter table test_name drop column VARCHAR2_NAME;
--重建
ALTER TABLE TEST_NAME ADD (VARCHAR2_NAME NVARCHAR2(200) );
--赋值
update test_name set VARCHAR2_NAME=TEMP;
--临时字段的使命完成了
alter table test_name drop column TEMP;
select * from test_name
insert into  test_name  values (2,(select utl_raw.cast_to_nvarchar2('d85fdff96307') from dual),(select utl_raw.cast_to_nvarchar2('d85fdff96307') from dual));

image.png


方法2:
基本不可行,一是停机时间太长,再就是改了字符集再重新导入的时候也可能会遇到字段长度不够的问题。
方法3:
就是真实案例,问了一下别家医院(几个不同厂家的HIS系统)是怎么解决这个问题的,结果。。。。就是写成(足母),别笑,真的好多家都这么搞的!!
 

image.png


另1家医院也是这样

image.png

总结后记

虽然这个能有办法解决。
但是还有一点我没想明白,人名生僻字他们咋解决的??难道人名的字段类型本来就是nvarchar2???
有知道的小伙伴可以告诉我一下,谢谢!

20240509

后来大佬们给的结果就是,在把varchar2改成nvarchar2,再重新录入。看来要整库都改生僻字是个大工程,1个1个改肯定是不好办。

image.png

 也欢迎关注我的公众号【徐sir的IT之路】,一起学习————————————————————————————
公众号:徐sir的IT之路
CSDN :https://blog.csdn.net/xxddxhyz?type=blog
墨天轮:https://www.modb.pro/u/3605
PGFANS:https://www.pgfans.cn/user/home?userId=5568————————————————————————————

这篇关于Oracle里令人头疼的生僻字处理案例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/973381

相关文章

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

Oracle查询表结构建表语句索引等方式

《Oracle查询表结构建表语句索引等方式》使用USER_TAB_COLUMNS查询表结构可避免系统隐藏字段(如LISTUSER的CLOB与VARCHAR2同名字段),这些字段可能为dbms_lob.... 目录oracle查询表结构建表语句索引1.用“USER_TAB_COLUMNS”查询表结构2.用“a

Oracle数据库定时备份脚本方式(Linux)

《Oracle数据库定时备份脚本方式(Linux)》文章介绍Oracle数据库自动备份方案,包含主机备份传输与备机解压导入流程,强调需提前全量删除原库数据避免报错,并需配置无密传输、定时任务及验证脚本... 目录说明主机脚本备机上自动导库脚本整个自动备份oracle数据库的过程(建议全程用root用户)总结

Python进行JSON和Excel文件转换处理指南

《Python进行JSON和Excel文件转换处理指南》在数据交换与系统集成中,JSON与Excel是两种极为常见的数据格式,本文将介绍如何使用Python实现将JSON转换为格式化的Excel文件,... 目录将 jsON 导入为格式化 Excel将 Excel 导出为结构化 JSON处理嵌套 JSON:

RabbitMQ消费端单线程与多线程案例讲解

《RabbitMQ消费端单线程与多线程案例讲解》文章解析RabbitMQ消费端单线程与多线程处理机制,说明concurrency控制消费者数量,max-concurrency控制最大线程数,prefe... 目录 一、基础概念详细解释:举个例子:✅ 单消费者 + 单线程消费❌ 单消费者 + 多线程消费❌ 多

Spring Boot 中的默认异常处理机制及执行流程

《SpringBoot中的默认异常处理机制及执行流程》SpringBoot内置BasicErrorController,自动处理异常并生成HTML/JSON响应,支持自定义错误路径、配置及扩展,如... 目录Spring Boot 异常处理机制详解默认错误页面功能自动异常转换机制错误属性配置选项默认错误处理

SpringBoot 异常处理/自定义格式校验的问题实例详解

《SpringBoot异常处理/自定义格式校验的问题实例详解》文章探讨SpringBoot中自定义注解校验问题,区分参数级与类级约束触发的异常类型,建议通过@RestControllerAdvice... 目录1. 问题简要描述2. 异常触发1) 参数级别约束2) 类级别约束3. 异常处理1) 字段级别约束

Java堆转储文件之1.6G大文件处理完整指南

《Java堆转储文件之1.6G大文件处理完整指南》堆转储文件是优化、分析内存消耗的重要工具,:本文主要介绍Java堆转储文件之1.6G大文件处理的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言文件为什么这么大?如何处理这个文件?分析文件内容(推荐)删除文件(如果不需要)查看错误来源如何避

使用Python构建一个高效的日志处理系统

《使用Python构建一个高效的日志处理系统》这篇文章主要为大家详细讲解了如何使用Python开发一个专业的日志分析工具,能够自动化处理、分析和可视化各类日志文件,大幅提升运维效率,需要的可以了解下... 目录环境准备工具功能概述完整代码实现代码深度解析1. 类设计与初始化2. 日志解析核心逻辑3. 文件处

Java docx4j高效处理Word文档的实战指南

《Javadocx4j高效处理Word文档的实战指南》对于需要在Java应用程序中生成、修改或处理Word文档的开发者来说,docx4j是一个强大而专业的选择,下面我们就来看看docx4j的具体使用... 目录引言一、环境准备与基础配置1.1 Maven依赖配置1.2 初始化测试类二、增强版文档操作示例2.