【问题标题】:Oracle Unicode Support in 10g and 11g Differences10g 和 11g 中的 Oracle Unicode 支持差异
【发布时间】:2012-01-02 15:29:23
【问题描述】:

我遇到了一个我还无法解释的问题。我有一个带数字的代码,使用 NCHR 获取该数字的国家字符代码,然后对其执行 RAWTOHEX 转换。

它在 10g 中工作了多年。当我们升级到 11g 时,它开始返回不同的值。我将其归结为几条语句,并创建了一个演示脚本:

SET SERVEROUTPUT ON;
DECLARE
  rawVar RAW(2000);
  nVar NVARCHAR2(1000);
BEGIN
  nVar :=  NCHR(1112);
  SELECT RAWTOHEX(nVar) INTO rawVar FROM DUAL;
  DBMS_OUTPUT.PUT_LINE('rawVar: ' || rawVar);
END;
/

在 10g 中执行时,输出为“0458”。在 11g 中(来自同一台计算机并使用相同的 Oracle 客户端软件)输出为“00040058”。依赖输出的上游进程期待“0458”。

有趣的是(对我而言),如果我将 nVar 的定义更改为 VARCHAR2 而不是 NVARCHAR2,我会在 11g 上得到“0458”作为输出。

有人可以帮忙解释为什么结果不同吗?我搜索了 Oracle 的发行说明和支持系统,但没有找到任何答案。

非常感谢。

【问题讨论】:

  • 你能从 SQL 环境中运行它吗:select nchr(1112) nchr, rawtohex(nchr(1112)) rth from dual;
  • 两个环境sreutrn相同,NCHR是“?” RTH 是“0458”
  • 所以,似乎在 dbms_output 中转换为 varchar 会影响值 - 这是否类似于您的上游进程接收值的方式?
  • 在上游进程中,原始变量通过 JDBC 传递回 Java 应用程序。从那里分析这些位并将其转换回原始值(漫长的过程)。使用相同的代码,我在 10g 和 11g 中得到两个不同的结果——这是我想不通的。

标签: oracle


【解决方案1】:

这是 Oracle 11 中的一个可怕错误 改变

nVar :=  NCHR(1112); 

nVar :=  CHR(1112 using nchar_cs);

一切都会重新开始。 根据 Oracle 文档,这些表达式应该是相同的。在 Oracle 10 中这是正确的,但在 11 中则不然。

【讨论】:

    【解决方案2】:

    这两个数据库是否使用相同的字符集?

    您能否在两种情况下都运行此查询:

    select value 
      from nls_database_parameters 
     where parameter='NLS_NCHAR_CHARACTERSET';
    

    只有当数据库具有相同的字符集时,CHR 和 NCHR 函数才会给出相同的结果。

    【讨论】:

    • 感谢您的快速回复。是的,它们都是“AL16UTF16”。
    【解决方案3】:

    RAWTOHEX 返回一个字符值,但您将其选择为 RAW,因此那里会有一些隐式转换。然后,您尝试使用 DBMS_OUTPUT,这需要将该 RAW 变量隐式转换为字符串。

    您可能可以处理 RAW 值(即字节)或字符值(可能会根据字符集/语言设置进行转换/翻译的文本)或字符串中字节的十六进制表示。您在数据库中有哪些,您希望将哪些返回到应用程序?然后只需进行一次转换并明确地进行。

    【讨论】:

    • 谢谢。我理解这种方法不是很合理。但是,我的问题是为什么相同的代码在 Oracle 10g 和 Oracle 11g 中返回不同的值。
    • 我怀疑在多字节字符集中将 RAW 隐式转换为 VARCHAR 的过程中发生了一些变化,但没有可供测试的数据库。
    猜你喜欢
    • 1970-01-01
    • 2011-08-13
    • 2023-03-29
    • 2018-03-27
    • 2023-03-17
    • 2018-05-22
    • 1970-01-01
    • 2012-07-29
    • 2015-09-04
    相关资源
    最近更新 更多