Tried working the script but special characters are getting changed to question mark.
-
2Possible duplicate of [Function to remove accents in postgreSQL](https://stackoverflow.com/questions/13596638/function-to-remove-accents-in-postgresql) – MTCoster Jan 18 '18 at 12:47
-
Try this: `SELECT CONVERT('ÜNLÜ, JÓNÁS', 'US7ASCII') FROM dual;` or better `UTL_RAW.CAST_TO_VARCHAR2(UTL_RAW.CONVERT(UTL_I18N.STRING_TO_RAW('ÜNLÜ, JÓNÁS'), 'US7ASCII', REGEXP_REPLACE(SYS_CONTEXT('USERENV', 'LANGUAGE'), '.*\.')))` – Wernfried Domscheit Jan 18 '18 at 14:32
-
Could you run the following command in SQL*Plus and tell us what it says, please? select value from nls_session_parameters where parameter = 'NLS_LANG'; Also, is the data-type column you are selecting from varchar2 or nvarchar2 (or char or nchar)? It appears that there is something wrong in this area. – Ron Ballard Jan 18 '18 at 14:42
-
What is your actual problem? Do you really have to convert characters to ASCII range or do you have a display issue? – Wernfried Domscheit Jan 18 '18 at 14:50
-
Your statement is completely useless. You replace string `US7ASCII` by `US7ASCII` - and this even two times. – Wernfried Domscheit Jan 18 '18 at 14:53
-
@RonBallard, I don't know your intention but I assume you mean `select value from V$NLS_PARAMETERS where parameter = 'NLS_CHARACTERSET';`. However, this shows the **database** character set, not the `NLS_LANG` value from your client. – Wernfried Domscheit Jan 18 '18 at 15:33
-
From the image and the question, I am guessing that the question marks represent characters that the Oracle client cannot convert, rather than actually being question marks. My intention is to find out why. My previous comment was incomplete, sorry. Oracle has, on the server, a character set defined for the database, and possibly a second character set for columns with data-type nchar or nvarchar2. It also has a character set defined for the client. There is apparently a mismatch, so we need to find these three settings. – Ron Ballard Jan 18 '18 at 16:47
-
`select * from nls_database_parameters where parameter like '%CHARACTERSET%';` will give us both server settings. We still need to know the exact data-type of the column being tested. `select value from nls_session_parameters where parameter = 'NLS_LANG';` gives us the client setting. – Ron Ballard Jan 18 '18 at 16:49
-
@RonBallard, `select value from nls_session_parameters where parameter = 'NLS_LANG';` does not return anything (at least up to Oracle 12.1). You cannot query client NLS_LANG value on database. – Wernfried Domscheit Jan 19 '18 at 08:03
1 Answers
Thanks to @Wernfried Domscheit for pointing out the flaws in my answer that may cause it not to work for you. I have now edited my answer to address those issues.
Firstly, in order to see and enter the accented characters, you need to have your client system working in a character set that supports these characters. US ASCII 7-bit does not support accented characters. (Explanation here.)
UTF-8 is now by far the most popular character set on the internet and is becoming more popular in commercial systems, because it does support just about every character system on the planet. Other character sets that support accented characters include the Windows-12xx family and the ISO-8859 family. If you can tell us more about the client system (Windows? Mac? UNIX?) and the application you are using to access the database, we can be more specific.
I can reproduce the symptoms of your problem and solve it in my case.
First of all I check the server characterset:
select * from nls_database_parameters where parameter like '%CHARACTERSET%';
PARAMETER VALUE
---------------------- ----------
NLS_CHARACTERSET AL32UTF8
NLS_NCHAR_CHARACTERSET AL16UTF16
So varchar2 columns will be encoded in UTF-8 on my server.
I'm running Oracle on Linux with $LANG=en.US.UTF-8 on my client. I can confuse the client by defining $NLS_LANG (for the client) to use an ISO-8859 character set:
$ export NLS_LANG=ENGLISH_AMERICA.WE8ISO8859P1
Then in SQL*Plus I select a varchar2 column:
select word from test;
and the result is:
WORD
--------------------------------
�B�D�FGH�J
The question marks (actually "unknown character") are highlighting the mismatch between the characters I selected and what I told the client to expect.
If, at the operating system prompt, I set $NLS_LANG to match the client set-up, like this:
$ export NLS_LANG=ENGLISH_AMERICA.AL32UTF8
and run exactly the same query on the same data in SQL*Plus:
select word from test;
the result is:
WORD
--------------------------------
ÁBÇDÉFGHÍJ
If your server is storing accented characters correctly then it must be using a character set that supports these (examples above). Your client also needs to support a character set that can handle accented characters and your NLS_LANG setting need to match what the client can support. How you do that will depend on what client system you are using.
When you have a client that can display, and allow you to enter, accented characters, then you can solve your original problem. You don't need a PL/SQL function to do the conversion, you simply use the Oracle translate function, like this:
select word, translate(word, 'ÁÇÉÍ', 'ACEI') as no_accents from test;
WORD NO_ACCENTS
---------- ----------
ÁBÇDÉFGHÍJ ABCDEFGHIJ

- 693
- 6
- 8
-
1You are wrong. `NLS_LANG` has to match your actual client character set. sqlplus inherits the character set from terminal. You can interrogate terminal character set by `locale charmap` or `echo $LANG`. Your solution is working because your **Linux** character set is `UTF-8` - regardless of database character set. On Windows you can easily change encoding of `cmd.exe` with command `chcp`, e.g. `chcp 28591 set NLS_LANG=.WE8ISO8859P1 sqlplus...` would also work in this case. See also https://stackoverflow.com/questions/33783902/odbcconnection-returning-chinese-characters-as/33790600#33790600 – Wernfried Domscheit Jan 19 '18 at 08:23