当前位置: 首页 > article >正文

解决Oracle11g的SQL Loader(sqlldr)命令行中文乱码问题

文章目录

  • (一)现象
  • (二)分析
    • (2.1)入库文件字符集?(No)
    • (2.2)客户端设置?(Yes)
    • (2.3)分析NLS_LANG设置
  • (三)解决(无奈)

结论:

Oracle 11g 的 SQL Loader(sqlldr)命令行输出的语言和字符集受到NLS_LANG环境变量控制。
比如:NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK表示使用简体中文语言和GBK编码。

有兴趣可以继续看下面啰嗦的分析过程内容。

(一)现象

程序在Linux下调用sqlldr时,发现其返回的命令行内容存在乱码。
手动测试sqlldr命令,果然和程序读到的一样,是乱码。
仔细检查发现是GBK格式,因为Linux下基本都默认UTF8编码,所以直接终端显示就变乱码了。

$shion@shionwsl ~> sqlldr

SQL*Loader: Release 11.2.0.4.0 - Production on ������ 4�� 27 09:08:30 2023
Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.

�÷�: SQLLDR keyword=value [,keyword=value,...]

��Ч�Ĺؼ���:

    userid -- ORACLE �û���/����
   control -- �����ļ���
       log -- ��־�ļ���
       bad -- �����ļ���
      data -- �����ļ���
   discard -- �����ļ���
   ......

回到Windows下调用同版本sqlldr,正常显示:

PS C:\Users\Shion> sqlldr

SQL*Loader: Release 11.2.0.4.0 - Production on 星期四 427 09:11:50 2023
Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.

用法: SQLLDR keyword=value [,keyword=value,...]

有效的关键字:

    userid -- ORACLE 用户名/口令
   control -- 控制文件名
       log -- 日志文件名
       bad -- 错误文件名
      data -- 数据文件名
   discard -- 废弃文件名
   ......

(二)分析

(2.1)入库文件字符集?(No)

我们都知道,文件内容如果带有中文是有编码的,所以调用sqlldr入库时,需要指定其编码。
这部分在控制文件.ctl中完成。
如下例,指定了ZHS16GBK 编码方式:

OPTIONS (skip=0) LOAD DATA CHARACTERSET ZHS16GBK 
INFILE 'xxxxx/eps.txt' 
APPEND INTO TABLE yyyyy 
FIELDS TERMINATED BY X'09' 
TRAILING NULLCOLS 
(xxxx char(16),yyyy,zzzz,......)

会不会因为导入的文件都是GBK编码影响了sqlldr的命令行输出呢?当然不是!!!
因为我们只输入了sqlldr命令本身,没有任何参数,中文已经是乱码了。

(2.2)客户端设置?(Yes)

既然Windows和Linux都输出GBK,而不是尊重操作系统的字符集(编码)……
那么是不是因为同样的客户端设置引起的呢?
两边都设置了:

NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK

尝试将Linux那边改为SIMPLIFIED CHINESE_CHINA.AL32UTF8
再调用sqlldr,果然没有乱码了。但 问题并没有解决!!!

因为Oracle客户端设置是需要和服务端一致的,既然服务端是GBK而客户端改为了UTF8,会导致你用SQL选出的中文变成乱码。这是Oracle一个很神奇的设置,它完全不考虑你需要同时连接2个不同字符集服务端的情况。Java已经不再读这个客户端配置,但也引发了其它的问题(之前有遇到过并记录到了文章)。

那怎么办呢?

(2.3)分析NLS_LANG设置

我们来看一下(当然还有很多其它国家和语言/字符集设置):

NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK
NLS_LANG=JAPANESE_JAPAN.AL32UTF8
NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P15
......

NLS_LANG的值,明显分为两部分:
中间用点连接,格式为:NLS_LANG=语言_国家 . 字符集

  1. 语言和国家
  2. 字符集(编码方式)

现在的问题是:

  • sqlldr的命令行显示,不尊重操作系统字符集,而是采用了NLS_LANG的字符集
  • 这个客户端的字符集设置又必须和服务端一致不能随便改。
  • Linux操作系统字符集是UTF8和ORACLE客户端字符集GBK不一样,导致冲突。

所以?改Linux操作系统字符集?当然不能!!!
随便改操作系统字符集,无异于单表有乱码改整个数据库字符集!!!
在生产系统中毫不考虑还其它程序在跑,⚠️属于破坏行为。
量刑标准我不清楚,同时一般人权限也不够。

(三)解决(无奈)

由于Oracle自身的设定的原因,通常情况下Linux的UTF8和Oracle服务端要求的GBK编码一定冲突。
用程序读取很简单,创建流读取命令行输出信息时,指定成NLS_LANG同样的编码就OK了。

但是人敲命令行怎么办呢???
只能看乱码么,还是每次设法转成看GBK?

刚才提到了既然分两部分,第二部分不能改,就只能看第一部分了,也就是语言_国家设置。
那就只能把语言改为任何编码下都能正常显示的语言:英语了。

NLS_LANG=AMERICAN_AMERICA.ZHS16GBK

谁说米国人不能说中文呢?
设置后如下,同时还解决了翻译成中文后看不懂的问题(手动狗头)。

$shion@shionwsl ~> sqlldr

SQL*Loader: Release 11.2.0.4.0 - Production on Thu Apr 27 10:01:24 2023
Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.

Usage: SQLLDR keyword=value [,keyword=value,...]

Valid Keywords:

    userid -- ORACLE username/password
   control -- control file name
       log -- log file name
       bad -- bad file name
      data -- data file name
   discard -- discard file name
   ......

http://www.kler.cn/a/15570.html

相关文章:

  • 代码段数据段的划分
  • 【Ubuntu24.04】使用服务器
  • windows工具 -- 使用rustdesk和云服务器自建远程桌面服务, 手机, PC, Mac, Linux远程桌面 (简洁明了)
  • 从建立TRUST到实现FAIR:可持续海洋经济的数据管理
  • Notepad++的完美替代
  • Android OpenGL ES详解——glTexImage2D方法
  • 分享10个精美可视化模板,解决95%的大屏需求!
  • 荔枝派Zero(全志V3S) tftp下载 kernel 和 nfs 挂载文件系统
  • 嵌入式开发--无刷电机学习1--FOC简介
  • 【DAY46】js的算法(1)
  • Duboo介绍与入门
  • 【Log4j RCE (CVE-2021-44228)】复现及原理分析
  • ASEMI代理ADI亚德诺ADM3051CRZ-REEL7车规级芯片
  • 一款免安装、多平台兼容的 拾色器(Color Picker)
  • C#开发的OpenRA游戏的加载地图流程
  • 【OAI】UERANSIM容器与OAI核心网分立部署及测试
  • 力扣第343场周赛
  • 【Git 入门教程】第七节、Git 远程仓库(Github)
  • MongoDB 聚合管道的输出结果到集合($out)及合并结果到集合($merge)
  • 什么是redis发布订阅模式,并用java代码实现小demo
  • 我们要被淘汰了?从科技变革看"ChatGPT"与"无代码开发"
  • 【数据库数据恢复】ORACLE常见数据灾难的数据恢复可能性分析
  • 【学习笔记】CF607E Cross Sum
  • 前端开发技术——对象
  • apple pencil有买的必要吗?便宜的平替电容笔推荐
  • [学习笔记] [机器学习] 3. KNN( K-近邻算法)及练习案例