【问题标题】:Oracle PLSQL equivalent of ASCIISTR(N'str')Oracle PLSQL 等效于 ASCIISTR(N'str')
【发布时间】:2016-06-22 16:10:13
【问题描述】:

我的数据库有NLS_LANGUAGE:AMERICAN / NLS_CHARACTERSET:WE8ISO8859P15 / NLS_NCHAR_CHARACTERSET:AL16UTF16NLS_LANG 在我的 Windows> 属性> 高级系统设置> 高级> 环境变量中设置为 AMERICAN_AMERICA.WE8MSWIN1252 - 希望它适用于我的 PLSQL 开发人员。

我使用ASCIISTR 为这样的奇异字符获取 unicode 编码值:

SELECT ASCIISTR(N'κόσμε') FROM DUAL;

结果

ASCIISTR(UNISTR('\03BA\1F79\03...
---------------------------------
\03BA\1F79\03C3\03BC\03B5

看起来“N”表示该字符串是 unicode,因为如果我不指定它,我会得到错误的编码。

SELECT ASCIISTR('κόσμε') FROM DUAL;

结果

ASCIISTR('??SµE')
--------------------
??s\00B5e

这个“N”代表什么?如何在 PLSQL 中调用它?

我打算在 pl/sql 变量上使用它来编码像这样的外来字符:

DECLARE 
  l_in VARCHAR2(2000);
  l_ec VARCHAR2(2000);
  l_dc VARCHAR2(2000);
BEGIN 
  l_in := 'κόσμε';
  execute immediate 'select ASCIISTR(N'''||l_in||''') from dual'  into l_ec;
  DBMS_OUTPUT.PUT_LINE(l_ec);

  select unistr(l_ec) into l_dc from dual;
  DBMS_OUTPUT.PUT_LINE (l_dc);
END;

但我明白了

??s\00B5e
??sµe

好像我在上面的第二种情况下,没有'N'

【问题讨论】:

    标签: oracle unicode plsql


    【解决方案1】:

    N'κόσμε' (或多或少)等价于CAST('κόσμε' AS NVARCHAR2(..))

    对于N'κόσμε',您说“将字符串视为 NVARCHAR”。如果您只写'κόσμε',则该字符串将被视为VARCHAR。但是,您的 NLS_CHARACTERSETWE8ISO8859P15,它不支持希腊字符。因此你得到? 作为占位符。

    您没有告诉我们您的 NLS_NCHARACTERSET 设置,很可能这支持 Unicode。

    顺便说一句,你不用select ... from dual,直接写like

    l_ec := ASCIISTR('κόσμε');
    

    在 PL/SQL 中。

    您的 本地 NLS_LANG 值是多少,即在您的客户端?它很可能与您的 SQL*Plus 的字符编码不匹配。有关详细信息,请参阅此答案:OdbcConnection returning Chinese Characters as "?"

    【讨论】:

    • NLS_NCHAR_CHARACTERSET:AL16UTF16 ;惭愧,我不知道如何从 PLSQL Developper 获取这个 NLS_LANG。
    • 我认为我的NLS_LANGAMERICAN_AMERICA.WE8MSWIN1252(来自windows env. variables)
    • cmd.exe 的默认代码页集(很可能)是 850,与 WE8MSWIN1252 不匹配。注意,SQL*Plus 继承父 cmd.exe 的代码页设置。他们必须匹配。顺便说一句,这是更改 cmd.exe 的默认代码页的解决方案:stackoverflow.com/questions/388490/…
    • 谢谢,但我不能在这里更改注册表。我将尝试更改 NLS_LANG
    【解决方案2】:

    我(遗憾地)在 PLSQL decode NVARCHAR2 from BASE64 to UTF-8 中发现 DBMS_OUTPUT 不支持 NVARCHAR2 数据类型。因此我不能用它来调试。

    然后我可以做以下测试:

    -- encoding
    CREATE OR REPLACE FUNCTION my_ec(l_in nvarchar2) RETURN varchar2 is
        l_out varchar2(32000);
    BEGIN    
        l_out := asciistr(l_in);
        return l_out;  
    END;
    /
    
    -- decoding
    CREATE OR REPLACE FUNCTION my_dc(l_in varchar2) RETURN nvarchar2 is
        l_out nvarchar2(32000);
    BEGIN 
        l_out := unistr(l_in);
        return l_out;
    END;
    /
    

    预期结果!

    select my_ec(N'κόσμε') from dual;
    --'\03BA\1F79\03C3\03BC\03B5'
    select my_dc('\03BA\1F79\03C3\03BC\03B5') from dual;
    --'κόσμε'
    select my_dc(my_ec(N'κόσμε')) from dual;
    --'κόσμε'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-01
      • 2023-03-08
      • 2011-05-01
      • 2013-05-08
      • 1970-01-01
      • 2015-05-31
      • 2014-05-30
      相关资源
      最近更新 更多