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

相关文章

电脑提示xlstat4.dll丢失怎么修复? xlstat4.dll文件丢失处理办法

《电脑提示xlstat4.dll丢失怎么修复?xlstat4.dll文件丢失处理办法》长时间使用电脑,大家多少都会遇到类似dll文件丢失的情况,不过,解决这一问题其实并不复杂,下面我们就来看看xls... 在Windows操作系统中,xlstat4.dll是一个重要的动态链接库文件,通常用于支持各种应用程序

SQL Server数据库死锁处理超详细攻略

《SQLServer数据库死锁处理超详细攻略》SQLServer作为主流数据库管理系统,在高并发场景下可能面临死锁问题,影响系统性能和稳定性,这篇文章主要给大家介绍了关于SQLServer数据库死... 目录一、引言二、查询 Sqlserver 中造成死锁的 SPID三、用内置函数查询执行信息1. sp_w

Java对异常的认识与异常的处理小结

《Java对异常的认识与异常的处理小结》Java程序在运行时可能出现的错误或非正常情况称为异常,下面给大家介绍Java对异常的认识与异常的处理,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参... 目录一、认识异常与异常类型。二、异常的处理三、总结 一、认识异常与异常类型。(1)简单定义-什么是

六个案例搞懂mysql间隙锁

《六个案例搞懂mysql间隙锁》MySQL中的间隙是指索引中两个索引键之间的空间,间隙锁用于防止范围查询期间的幻读,本文主要介绍了六个案例搞懂mysql间隙锁,具有一定的参考价值,感兴趣的可以了解一下... 目录概念解释间隙锁详解间隙锁触发条件间隙锁加锁规则案例演示案例一:唯一索引等值锁定存在的数据案例二:

Oracle修改端口号之后无法启动的解决方案

《Oracle修改端口号之后无法启动的解决方案》Oracle数据库更改端口后出现监听器无法启动的问题确实较为常见,但并非必然发生,这一问题通常源于​​配置错误或环境冲突​​,而非端口修改本身,以下是系... 目录一、问题根源分析​​​二、保姆级解决方案​​​​步骤1:修正监听器配置文件 (listener.

Golang 日志处理和正则处理的操作方法

《Golang日志处理和正则处理的操作方法》:本文主要介绍Golang日志处理和正则处理的操作方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录1、logx日志处理1.1、logx简介1.2、日志初始化与配置1.3、常用方法1.4、配合defer

springboot加载不到nacos配置中心的配置问题处理

《springboot加载不到nacos配置中心的配置问题处理》:本文主要介绍springboot加载不到nacos配置中心的配置问题处理,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录springboot加载不到nacos配置中心的配置两种可能Spring Boot 版本Nacos

MySQL 表的内外连接案例详解

《MySQL表的内外连接案例详解》本文给大家介绍MySQL表的内外连接,结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录表的内外连接(重点)内连接外连接表的内外连接(重点)内连接内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选,我

python web 开发之Flask中间件与请求处理钩子的最佳实践

《pythonweb开发之Flask中间件与请求处理钩子的最佳实践》Flask作为轻量级Web框架,提供了灵活的请求处理机制,中间件和请求钩子允许开发者在请求处理的不同阶段插入自定义逻辑,实现诸如... 目录Flask中间件与请求处理钩子完全指南1. 引言2. 请求处理生命周期概述3. 请求钩子详解3.1

Python处理大量Excel文件的十个技巧分享

《Python处理大量Excel文件的十个技巧分享》每天被大量Excel文件折磨的你看过来!这是一份Python程序员整理的实用技巧,不说废话,直接上干货,文章通过代码示例讲解的非常详细,需要的朋友可... 目录一、批量读取多个Excel文件二、选择性读取工作表和列三、自动调整格式和样式四、智能数据清洗五、