Oracle PLSQL equivalent of ASCIISTR(N'str')

爷,独闯天下 提交于 2020-02-03 01:59:13

问题


My database has NLS_LANGUAGE:AMERICAN / NLS_CHARACTERSET:WE8ISO8859P15 / NLS_NCHAR_CHARACTERSET:AL16UTF16; NLS_LANG is set to AMERICAN_AMERICA.WE8MSWIN1252 in my Windows> properties> advanced system settings> advanced> environment variables - hope it applies to my PLSQL Dev.

I use ASCIISTR to get a unicode encoded value for exotic chars like this:

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

Results in

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

It looks like the 'N' means the string is unicode, because if I don't specify it I get it wrong encoded.

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

Results in

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

What does this 'N' stands for? How do I invoke it in PLSQL?

I intend to use it on a pl/sql variable to encode exotice characters like this:

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;

But I get

??s\00B5e
??sµe

As if I were in the second case above, without the 'N'


回答1:


N'κόσμε' is (more or less) equivalent to CAST('κόσμε' AS NVARCHAR2(..))

With N'κόσμε' you say "treat the string as NVARCHAR". If you write just 'κόσμε' then the string is treated as VARCHAR. However, your NLS_CHARACTERSET is WE8ISO8859P15 which does not support Greek characters. Thus you get ? as placeholder.

You didn't tell us your NLS_NCHARACTERSET setting, most likely this supports Unicode.

btw, you don't have to select ... from dual, simply write like

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

in PL/SQL.

What is your local NLS_LANG value, i.e. at your client side? Most likely it does not match the character encoding of your SQL*Plus. See this answer for more details: OdbcConnection returning Chinese Characters as "?"




回答2:


I (sadly) discovered in PLSQL decode NVARCHAR2 from BASE64 to UTF-8 that DBMS_OUTPUT doesn't support NVARCHAR2 datatype. I thusly can't use it to debug.

Then I can do the following to test:

-- 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;
/

with expected result!

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;
--'κόσμε'


来源:https://stackoverflow.com/questions/37923536/oracle-plsql-equivalent-of-asciistrnstr

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!