改变容器中Oracle XE数据库的字符集

把Oracle XE用于为开发者搭建个人的开发环境虽然比较轻便,但是要想做到可随时的环境重建,最好还是借助容器技术。目前Oracle还没有官方提供的XE版镜像,在docker hub上却能找到很多人做出的镜像了。

问题

用 docker.io/alexeiled/docker-oracle-xe-11g 是不错的选择,但再好的选择也不能包治百病,在使用中也会遇到需要你自己来理的问题,比如字符集这个'水土不服'的问题。在通过容器提供的机制执行建库和数据库导入时也会遇到汉字出现乱码,以及插入数据超长,和sql脚本执行中提示语句不完整等错误。

原因

当然出现中文乱码要从字符集来来考虑原因,在与数据库相关时则要考虑的更多,比如:数据库的字符集,会话的字符集,客户端显示所用的字符集,所执行的sql脚本的字符集等。其中处理不当就会出现脚本不能被正常解释(提示脚本错误),数据不能被正常显示(数据被混乱转码,最终显示为乱码),数据溢出(在不同字符集下长度不同导致子串超长)等。

处理

在制作oracle xe镜像中执行的类似于静默安装,在11g中还不能指定数据库的字符集(在高版本中可以了),建立的数据库的字符集是AL32UTF8,如果通过容器启动中执行sql进行数据库的初始化,则也会因为sqlplus会话与所执行的sql文件的字符集的不匹配导致转码后数据编码损坏而变乱的。所以要做到如下三点:

  1. 修改数据库的字符集
  2. 通过环境变量控制会话的字符集
  3. 确保sql文件的字符集和会话字符集一致

最后虽然做到客户端显示所用的字符集与会话的字符集一致也很关键,但却它只影响显示,不会导致数据损坏或执行异常,不如以上几点重要。

  • 修改数据库的字符集

修改字符集的操作是通过如下的代码

sql> shutdown immediate;
sql> startup restrict;
sql> ALTER DATABASE character set INTERNAL_USE ZHS16GBK;
sql> shutdown immediate;
sql> startup;
sql> quit;

上述命令将字符集转变为ZHS16GBK。
为能在容器启动时执行以上命令,把它们写入的一个shell脚本中,通过控制台输入重定向加载以在容器启动时被执行,另外为了能直接以sysdba执行把执行的用户切换为oracle, 因此才有【参见链接】内中的脚本文件。

在shell脚本中通过输入重定向执行sql脚本

[root@002 ]# cat changeset.shx 
#!/bin/sh

/u01/app/oracle/product/11.2.0/xe/bin/sqlplus / as sysdba<<EOF
shutdown ...;
...
startup;
quit;
EOF

作为oracle用户执行shell脚本

#!/bin/sh

su  oracle -s /etc/entrypoint-initdb.d/changeset.shx

  • 通过环境变量控制会话的字符集
    在容器中通过sqlplus执行挂载目录中的sql文件,但sqlplus在执行时根据其环境选择与服务器会话的字符集,为保证包含着中文信息的sql文件能被正确解析,需要通过设置NLS_LANG来确保会话使用了预定的字符集。去构建新的镜像设置语言环境是一种方式,但也仅为此就去构建一个新的镜像。通过启动容器时用-e 设置环境变量就可以实现,比如:
docker run -d --shm-size=1g -p 8080:8080 -p 1521:1521 \
-e NLS_LANG="SIMPLIFIED CHINESE_CHINA.UTF8" \
-v /local-initdb:/etc/entrypoint-initdb.d alexeiled/docker-oracle-xe-11g

它把会话字符集设置为了UTF8

  • 确保sql文件的字符集和会话字符集一致
    通过notepad++等工具把sql文件的字符集转换为和会话一致的(如上是UTF8)。

示例参见链接
脚本名称为a.sh是为了它能被第一执行。

另外,虽然用容器启动oracle xe是比较便捷的,但是缺点是在容器重新启动时会出现重新初始化数据和数据丢失的问题,为避免应该通过存储挂载把库文件持久化到容器外面,并需要在初始化脚本中加上判断和处理,在数据文件已经存在时不执行初始化脚本而是进行已有文件的导入处理,这计划另起篇章。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容