Why is "?" Displayed in lowercase "i"? after executing NLS_UPPER
Can someone please explain why lowercase i
in a string is abcdefghijklmnopqrstuvwxyz
matched to ?
, whereas all other alphabets map to matching uppercase correctly.
SQL> ALTER SESSION SET NLS_SORT="xturkish";
Session altered.
SQL>
SQL> begin
2 DBMS_OUTPUT.PUT_LINE('NLS_UPPER(abcdefghijklmnopqrstuvwxyz) = '
3 || NLS_UPPER('abcdefghijklmnopqrstuvwxyz'));
4 end;
5 /
NLS_UPPER(abcdefghijklmnopqrstuvwxyz) = ABCDEFGH?JKLMNOPQRSTUVWXYZ
PL/SQL procedure successfully completed.
SQL>
Update: if nls_sort is set to BINARY, the mapping happens as expected, the lower case is i
mapped to the English alphabet planei
source to share
Capital i
in Turkish İ
(U + 0130: latin letter i with dot above), see https://codepoints.net/U+0130
The Turkish alphabet, which is a variant of the Latin alphabet, includes two different versions of the letter I, one dotted and the others countless.
Infinite I, I ı, denotes a closed reverse unbaked vowel sound (/ Ɯ /). Neither the top nor the bottom version has a dot.
Dotted I, İ i, denotes a close front without a circular vowel (/ i /). Both upper and lower case variants have a period.
Examples:
İstanbul / istanbuɫ / (starts with the sound i, not ı).
Diyarbakır / dijaɾbakɯɾ / (the first and last vowels are written and pronounced differently)
It looks like your database character set does not support this character, what is your database character set? Check with
SELECT *
FROM V$NLS_PARAMETERS
WHERE PARAMETER IN ('NLS_CHARACTERSET', 'NLS_NCHAR_CHARACTERSET');
I guess
DBMS_OUTPUT.PUT_LINE('NLS_UPPER(abcdefghijklmnopqrstuvwxyz) = '
|| NLS_UPPER(N'abcdefghijklmnopqrstuvwxyz'));
must work.
You must set your NLS_LANG
and console encoding correctly for correct output. Here are some working examples:
C:\>set NLS_LANG=.AL32UTF8
C:\>chcp 65001
Active code page: 65001
C:\>sqlplus ...
select nls_upper('i', 'nls_sort = xturkish') from dual;
C:\>set NLS_LANG=.TR8MSWIN1254
C:\>chcp 1254
Active code page: 1254
C:\>sqlplus ...
select nls_upper('i', 'nls_sort = xturkish') from dual;
C:\>set NLS_LANG=.SE8ISO8859P3
C:\>chcp 28593
Active code page: 28593
C:\>sqlplus ...
select nls_upper('i', 'nls_sort = xturkish') from dual;
C:\>set NLS_LANG=.WE8ISO8859P9
C:\>chcp 28599
Active code page: 28599
C:\>sqlplus ...
select nls_upper('i', 'nls_sort = xturkish') from dual;
source to share
I cannot explain it because I cannot reproduce it. There must be something wrong on your machine. Here is my session, copied and pasted from SQL * Plus:
SQL> set serveroutput on
SQL> ALTER SESSION SET NLS_SORT="xturkish";
Session altered.
Elapsed: 00:00:00.01
SQL> begin
2 DBMS_OUTPUT.PUT_LINE('NLS_UPPER(abcdefghijklmnopqrstuvwxyz) = '
3 || NLS_UPPER('abcdefghijklmnopqrstuvwxyz'));
4 end;
5 /
NLS_UPPER(abcdefghijklmnopqrstuvwxyz) = ABCDEFGHIJKLMNOPQRSTUVWXYZ
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.00
SQL>
source to share