NLS

您所在的位置:网站首页 oracle查询字符集编码 NLS

NLS

2024-07-08 23:09| 来源: 网络整理| 查看: 265

在 UNIX 系统上以 US7ASCII 字符集创建一个数据库。连接至数据库的 Windows 客户端使用 WE8MSWIN1252 字符集(区域设置 -> 西欧/ACP 1252),DBA 则使用 UNIX shell (ROMAN8) 操作数据库。客户端和服务器上的 NLS_LANG 设置为 american_america.US7ASCII。

Note: This is an INCORRECT setup to explain character set conversion, don't use it in your environment!

请重点注意以下要点(如前所述):

当客户端 NLS_LANG 字符集设置为与数据库字符集相同的值时,Oracle 会认为发送或接收的数据具有相同(正确)的编码,因此出于性能方面的考虑,可能不会进行任何转换或验证。客户端传递的数据将会逐比特地原样进行存储。

从 Windows 中将一个 ‘é’(带尖音符的小写拉丁字母)插入到包含一个 'char' 类型的 ‘TEST’ 列的 NLS_TEST 表中。

只要您是在使用 WE8MSWIN1252 字符集的 Windows 系统上对该列执行插入和选择操作,那么一切都会顺利运行。即便数据库的字符集定义为了 7 位,系统也不会进行任何转换,并且会插入 8 位并读回 8 位。这是因为一个字节是 8 位,而 Oracle 始终使用 8 位,即便在 7 位字符集的情况下也是如此。在正确的设置下,系统不会处理最高有效位,而只会处理 7 位。

出于某种原因,您需要从 UNIX 服务器进行插入。在对 Windows 客户端插入数据的表执行 SELECT 操作时,您会获得 ‘Ò’(带沉音符的大写拉丁字母 O),而不是 ‘é’。

如果在 UNIX 服务器上插入 ‘é’ 而在 Windows 客户端上对该行执行 SELECT 操作,则会获得 ‘Å’(顶部带圆圈的大写拉丁字母 A)。

根本原因在于,您数据库中的数据是不正确的。您要将 WE8MSWIN1252 字符集的 ‘é’ 的数值存储在数据库中,但您告诉 Oracle 这是 US7ASCII 数据,因此 Oracle 不会进行任何转换,而只是存储该数值(再次重申:由于 NLS_LANG 设置为 US7ASCII,因此 Oracle 认为客户端提供的是 US7ASCII 代码,并且由于数据库字符集也是 US7ASCII,因此,系统不会进行任何转换)。

当您在 UNIX 服务器上对同一列执行 SELECT 操作时,Oracle 同样认为该值是正确的,不对该值进行任何转换就将其传递给 UNIX 终端。

问题是,在 WE8MSWIN1252 字符集中,‘é’ 的十六进制值是 'E9’,而在 Roman8 字符集中,‘é’ 的十六进制值是 'C5'。Oracle 只是将数据库中存储的值 ('E9') 传递给 UNIX 终端,而 UNIX 终端认为这是字母 ‘?’,因为在其 (Roman8) 字符集中,十六进制值 'E9' 代表字母 ‘Ò’。因此,您将在 UNIX 终端屏幕上看到 ‘Ò’ 而不是 ‘é’ 。

反之,如果在 UNIX 上执行插入操作,然后在 Windows 客户端上执行 SELECT 操作,情况也是相同的,只是您会得到其他结果。

对此的解决办法是,在创建数据库时使用包含 ‘é’ 的字符集

(WE8MSWIN1252、WE8ISO89859P1、UTF-8 等),并将客户端和服务器上的 NLS_LANG 分别设置为 WE8MSWIN1252 和 WE8ROMAN8。此时如果您在客户端和服务器上插入 ‘é’,那么无论从哪个系统执行 SELECT 操作,您都将得到 ‘é’。Oracle 知道 UNIX 插入的十六进制值的 'C5’ 以及 WE8MSWIN1252 客户端插入的 'E9’ 均是 ‘é’,并且会在数据库中插入 ‘é’(数据库中的代码取决于您所选择的字符集)。

您不必在 UNIX、Windows 或其他 OS 客户端之间切换就能发现此类问题。如果您添加别的 Windows 客户端,让其使用另一种字符集并采用错误的 NLS_LANG 设置,则会出现相同的问题。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3