特殊字符(德语变音符号)显示为 ASCII
Special characters (german umlauts) are displayed as ASCII
在我们的数据库中,德语变音符号显示为 ASCII。
这里有一些例子
Ü is displayed as "š"
ä is displayed as "„"
Ä is displayed as "Ž"
ö is displayed as "”"
Ö is displayed as "™"
这里是一些 Oracle 环境变量:
SELECT distinct client_charset FROM v$session_connect_info
WHERE sid = sys_context('USERENV','SID');
retuns Unknown
select * from v$NLS_PARAMETERS;
NLS_LANGUAGE GERMAN
NLS_CHARACTERSET WE8MSWIN1252
我也注意到,没有设置 NLS_LANG
。
有人能告诉我如何检查这是环境变量还是字符编码本身的问题吗?或者如何修复它以便正确显示变音符号?
提前致谢!
第一句话已经错了,一定是“我的客户端应用程序将德语变音符号显示为...” Ž
之类的字符也不是 ASCII。 Oracle 环境变量与您的客户端如何显示任何字符无关。
可能有两个原因:
像š „ Ž ” ™
这样的字符实际上存储在你的数据库中,因为它们插入错误,你只是认为它应该是Ü ä Ä ö Ö
您的客户端使用了错误的字符集。
NLS_LANG
用于告诉数据库“我的客户端使用字符集 XYZ”——不多也不少!好吧,一些客户端继承了自己的字符集设置的 NLS_LANG
值,但情况并非总是如此。
实际答案:
您的数据库中有错误的数据!当您插入数据时,您的客户端正在使用 CP437(Oracle 字符集 US8PC437
),但您没有告诉数据库。
最有可能的数据是由 sqlplus
插入的,它继承了 cmd.exe
的代码页,在英语 Windows 机器上默认为 437。 NLS_LANG
字符集设置为 WE8MSWIN1252
。当客户端和数据库的字符集相同时,数据传输 byte-by-byte 没有任何转换 - 存在不匹配!
解法:
在你 运行 你的 sqlplus
脚本之前相应地设置 NLS_LANG,例如
SET NLS_LANG=.US8PC437
sqlplus ...
语言和地区是可选的,因此可以跳过。
您的数据库使用字符集WE8MSWIN1252
,那么您的客户也可以使用它。通过这个你可以插入和显示数据库支持的任何字符(不多也不少)
chcp 1252
SET NLS_LANG=.WE8MSWIN1252
sqlplus ...
更正错误数据:
为了更正错误的数据试试这个:
UPDATE table_name SET column_name = CONVERT(column_name, 'WE8MSWIN1252', 'US8PC437');
请注意,这应该只是 one-time 更正。不要将此类更新作为应用程序代码的一部分!
更新
要更正 PL/SQL 代码,请尝试这个(未测试):
像这样创建一个 SQL 脚本:
SET HEADING OFF
SET FEEDBACK OFF
SET NEWPAGE NONE
SET VERIFY OFF
SET TRIMSPOOL ON
SET DEFINE OFF
SET ECHO OFF
SET TERMOUT OFF
SET PAGESIZE 0
SET LINESIZE 32767
SET LONG 2000000000
SET LONGCHUNKSIZE 32767
spool PACKAGE_NAME.sql;
SELECT DBMS_METADATA.GET_DDL('PACKAGE', 'PACKAGE_NAME', USER) FROM DUAL t;
spool OFF;
EXIT
而 运行 是这样的
c:\> chcp 437
c:\> SET NLS_LANG=.WE8MSWIN1252
c:\> sqlplus -s ... @<above script>
c:\> SET NLS_LANG=.US8PC437
c:\> sqlplus ... @PACKAGE_NAME.sql
在我们的数据库中,德语变音符号显示为 ASCII。 这里有一些例子
Ü is displayed as "š"
ä is displayed as "„"
Ä is displayed as "Ž"
ö is displayed as "”"
Ö is displayed as "™"
这里是一些 Oracle 环境变量:
SELECT distinct client_charset FROM v$session_connect_info
WHERE sid = sys_context('USERENV','SID');
retuns Unknown
select * from v$NLS_PARAMETERS;
NLS_LANGUAGE GERMAN
NLS_CHARACTERSET WE8MSWIN1252
我也注意到,没有设置 NLS_LANG
。
有人能告诉我如何检查这是环境变量还是字符编码本身的问题吗?或者如何修复它以便正确显示变音符号?
提前致谢!
第一句话已经错了,一定是“我的客户端应用程序将德语变音符号显示为...” Ž
之类的字符也不是 ASCII。 Oracle 环境变量与您的客户端如何显示任何字符无关。
可能有两个原因:
像
š „ Ž ” ™
这样的字符实际上存储在你的数据库中,因为它们插入错误,你只是认为它应该是Ü ä Ä ö Ö
您的客户端使用了错误的字符集。
NLS_LANG
用于告诉数据库“我的客户端使用字符集 XYZ”——不多也不少!好吧,一些客户端继承了自己的字符集设置的 NLS_LANG
值,但情况并非总是如此。
实际答案:
您的数据库中有错误的数据!当您插入数据时,您的客户端正在使用 CP437(Oracle 字符集 US8PC437
),但您没有告诉数据库。
最有可能的数据是由 sqlplus
插入的,它继承了 cmd.exe
的代码页,在英语 Windows 机器上默认为 437。 NLS_LANG
字符集设置为 WE8MSWIN1252
。当客户端和数据库的字符集相同时,数据传输 byte-by-byte 没有任何转换 - 存在不匹配!
解法:
在你 运行 你的
sqlplus
脚本之前相应地设置 NLS_LANG,例如SET NLS_LANG=.US8PC437 sqlplus ...
语言和地区是可选的,因此可以跳过。
您的数据库使用字符集
WE8MSWIN1252
,那么您的客户也可以使用它。通过这个你可以插入和显示数据库支持的任何字符(不多也不少)chcp 1252 SET NLS_LANG=.WE8MSWIN1252 sqlplus ...
更正错误数据:
为了更正错误的数据试试这个:
UPDATE table_name SET column_name = CONVERT(column_name, 'WE8MSWIN1252', 'US8PC437');
请注意,这应该只是 one-time 更正。不要将此类更新作为应用程序代码的一部分!
更新
要更正 PL/SQL 代码,请尝试这个(未测试):
像这样创建一个 SQL 脚本:
SET HEADING OFF
SET FEEDBACK OFF
SET NEWPAGE NONE
SET VERIFY OFF
SET TRIMSPOOL ON
SET DEFINE OFF
SET ECHO OFF
SET TERMOUT OFF
SET PAGESIZE 0
SET LINESIZE 32767
SET LONG 2000000000
SET LONGCHUNKSIZE 32767
spool PACKAGE_NAME.sql;
SELECT DBMS_METADATA.GET_DDL('PACKAGE', 'PACKAGE_NAME', USER) FROM DUAL t;
spool OFF;
EXIT
而 运行 是这样的
c:\> chcp 437
c:\> SET NLS_LANG=.WE8MSWIN1252
c:\> sqlplus -s ... @<above script>
c:\> SET NLS_LANG=.US8PC437
c:\> sqlplus ... @PACKAGE_NAME.sql