ITPub博客

首页 > 数据库 > Oracle > [20240820]字符集与dml语句.txt

[20240820]字符集与dml语句.txt

原创 Oracle 作者:lfree 时间:2024-08-20 21:58:04 0 删除 编辑

[20240820]字符集与dml语句.txt

--//测试看看不同环境不同字符集插入数据到表中,会出现怎么情况.

1.环境:
SCOTT@book01p> @ pr
==============================
PORT_STRING                   : x86_64/Linux 2.4.xx
VERSION                       : 21.0.0.0.0
BANNER                        : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
BANNER_FULL                   : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
BANNER_LEGACY                 : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
CON_ID                        : 0
PL/SQL procedure successfully completed.

--//linux:
# cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)

# echo $LANG
en_US.UTF-8

SCOTT@book01p> select * from v$nls_parameters ;
PARAMETER                      VALUE                                    CON_ID
------------------------------ ------------------------------------ ----------
NLS_LANGUAGE                   AMERICAN                                      3
NLS_TERRITORY                  AMERICA                                       3
NLS_CURRENCY                   $                                             3
NLS_ISO_CURRENCY               AMERICA                                       3
NLS_NUMERIC_CHARACTERS         .,                                            3
NLS_CALENDAR                   GREGORIAN                                     3
NLS_DATE_FORMAT                YYYY-MM-DD HH24:MI:SS                         3
NLS_DATE_LANGUAGE              AMERICAN                                      3
NLS_CHARACTERSET               ZHS16GBK                                      3
NLS_SORT                       BINARY                                        3
NLS_TIME_FORMAT                HH.MI.SSXFF AM                                3
NLS_TIMESTAMP_FORMAT           YYYY-MM-DD HH24:MI:SS.FF                      3
NLS_TIME_TZ_FORMAT             HH24.MI.SSXFF TZH:TZM                         3
NLS_TIMESTAMP_TZ_FORMAT        YYYY-MM-DD HH24:MI:SS.FF TZH:TZM              3
NLS_DUAL_CURRENCY              $                                             3
NLS_NCHAR_CHARACTERSET         AL16UTF16                                     3
NLS_COMP                       BINARY                                        3
NLS_LENGTH_SEMANTICS           BYTE                                          3
NLS_NCHAR_CONV_EXCP            FALSE                                         3
19 rows selected.
--//建立数据库字符集NLS_CHARACTERSET=ZHS16GBK,而NLS_NCHAR_CHARACTERSET=AL16UTF16,这种情况几乎是前几年大部分数据库的建立
--//模式,至少我们团队建立的数据库基本都是这样.

2.测试:
SCOTT@book01p> create table t1 (id number ,vc varchar2(20),nvc nvarchar2(40));
Table created.

--//在linux服务端插入:
SCOTT@book01p> insert into t1 values (1,'1测试2','a测试b');
1 row created.

SCOTT@book01p> commit;
Commit complete.

--//在windows客户端插入:
SCOTT@book01p> insert into t1 values (2,'3测试4','c测试d');
1 row created.

SCOTT@book01p> commit ;
Commit complete.

--//显示看看:
--//在linux服务端执行:
SCOTT@book01p> select * from t1;
        ID VC                   NVC
---------- -------------------- -------------
         2 3?               c?
         1 1测试2             a测试b         --//linux下插入的正常显示

--//在windows客户端执行:
SCOTT@book01p> select * from t1;
        ID VC                   NVC
---------- -------------------- ------------
         2 3测试4               c测试d     --//windows下插入的正常显示
         1 1娴嬭瘯2             a娴嬭瘯b

--//各个环境仅仅显示DML的结果是正确的,而实际上对于当前的环境在服务端操作插入是错误的.特别注意!!

3.继续:
--//重新登录,选择LANG=en_US,kitty Remote character set 选择 Use font encoding.
--//安全期间我修改/etc/locale.conf文件:
# cat locale.conf
#LANG="en_US.UTF-8"
LANG="en_US"

--//再重新登录.

$ echo $LANG
en_US

$ echo 张|xxd -c 16
0000000: d5c5 0a                                  ...

--//在linux服务端插入:
SCOTT@book01p> insert into t1 values (3,'5测试6','e测试f');
1 row created.

SCOTT@book01p> commit;
Commit complete.
--//注:我的测试本来是在winodws下使用vim事先写好语句,但是无法实现copy and paste.只能手工在linux下输入.
--//也许我的kitty版本太新的缘故.

--//再次显示看看:
--//在linux服务端执行:
SCOTT@book01p> select * from t1 order by 1;
        ID VC                   NVC
---------- -------------------- ---------
         1 1娴嬭瘯2             a娴嬭瘯b
         2 3测试4               c测试d
         3 5测试6               e测试f    --//这次linux的插入正确.

SCOTT@book01p> select dump(vc,16) c40 ,dump(nvc,16) c50,t1.* from t1 order by id;
C40                                      C50                                                        ID VC                   NVC        
---------------------------------------- -------------------------------------------------- ---------- -------------------- -----------
Typ=1 Len=8: 31,e6,b5,8b,e8,af,95,32     Typ=1 Len=10: 0,61,5a,34,5b,2d,76,2f,0,62                   1 1娴嬭瘯2             a娴嬭瘯b   
Typ=1 Len=6: 33,b2,e2,ca,d4,34           Typ=1 Len=8: 0,63,6d,4b,8b,d5,0,64                          2 3测试4               c测试d     
Typ=1 Len=6: 35,b2,e2,ca,d4,36           Typ=1 Len=8: 0,65,6d,4b,8b,d5,0,66                          3 5测试6               e测试f    --//这次linux的插入正确.

--//在windows客户端执行:
SCOTT@book01p> select * from t1 order by 1;
        ID VC                   NVC
---------- -------------------- --------------------
         1 1娴嬭瘯2             a娴嬭瘯b
         2 3测试4               c测试d
         3 5测试6               e测试f

4.总结:
--//如果你安装linux使用LANG="en_US.UTF-8",putty或者kitty设置Remote character set 选择 utf-8时,注意尽量不要在服务端执行
--//涉及中文字符的dml操作,否则可能导致乱码.
--//而且以前建立的数据库选择基本都是characterSet ZHS16GBK -nationalCharacterSet AL16UTF16

--//而且我目前总有一种感觉,统一到utf-8也许是大势所趋,至少许多软件都有这个的趋势.我下载最新vim 9.0,kitty,安装最新的linux
--//发布都遇到类似的问题.

# Silent mode.
dbca -silent -createDatabase                                                   \
     -templateName General_Purpose.dbc                                         \
     -gdbname ${ORACLE_SID} -sid  ${ORACLE_SID} -responseFile NO_VALUE         \
     -characterSet AL32UTF8                                                    \
     -sysPassword SysPassword1                                                 \
     -systemPassword SysPassword1                                              \
     -createAsContainerDatabase true                                           \
     -numberOfPDBs 1                                                           \
     -pdbName ${PDB_NAME}                                                      \
     -pdbAdminPassword PdbPassword1                                            \
     -databaseType MULTIPURPOSE                                                \
     -memoryMgmtType auto_sga                                                  \
     -totalMemory 2000                                                         \
     -storageType FS                                                           \
     -datafileDestination "${DATA_DIR}"                                        \
     -redoLogFileSize 50                                                       \
     -emConfiguration NONE                                                     \
     -ignorePreReqs
--//不知道是否有人测试过-characterSet AL32UTF8的情况.

5.收尾:
--//修改/etc/locale.conf文件:
# cat locale.conf
LANG="en_US.UTF-8"


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/267265/viewspace-3025527/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
熟悉oracle相关技术,擅长sql优化,rman备份与恢复,熟悉linux shell编程。

注册时间:2008-01-03

  • 博文量
    4006
  • 访问量
    7970878